This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Ctrl+Alt+I.

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Ctrl+Shift+K to preview the HTML file).

The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.

#Install packages

install.packages("BiocManager")
BiocManager::install("dada2", version = "3.11")

install.packages("qiime2R")
install.packages("tidyverse")
install.packages("biomformat")
install.packages('vegan')
install.packages('readr')
 
#Load packages

library("tidyverse")
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
-- Attaching packages --------------------------------------------------------------------------------------------- tidyverse 1.3.0 --
v ggplot2 3.3.2     v purrr   0.3.4
v tibble  3.0.3     v dplyr   1.0.2
v tidyr   1.1.2     v stringr 1.4.0
v readr   1.3.1     v forcats 0.5.0
-- Conflicts ------------------------------------------------------------------------------------------------ tidyverse_conflicts() --
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
library("dada2")
Loading required package: Rcpp
library("biomformat")
library('vegan')
Loading required package: permute
Loading required package: lattice
This is vegan 2.5-6
library('readr')
library("dplyr")     # To manipulate dataframes
library("readxl")    # To read Excel files into R
library("ggplot2")   # for high quality graphics
library("BiocManager")
Bioconductor version 3.11 (BiocManager 1.30.10), ?BiocManager::install for help
Bioconductor version '3.11' is out-of-date; the current release version '3.12' is available with R version '4.0'; see
  https://bioconductor.org/install
library("phyloseq")   
library("tidyr")
library("data.table")
data.table 1.13.0 using 2 threads (see ?getDTthreads).  Latest news: r-datatable.com

Attaching package: 㤼㸱data.table㤼㸲

The following objects are masked from 㤼㸱package:dplyr㤼㸲:

    between, first, last

The following object is masked from 㤼㸱package:purrr㤼㸲:

    transpose
#Merging tables for species abundance 1
#http://www.cookbook-r.com/Manipulating_data/Converting_data_between_wide_and_long_format/



###read in SILVA biom-taxonomy for SILVA ####################################################

taxonomy45 <- read.csv("G:/Desktop/Folders/Edu/2] EAS/Thesis/Real_Content/Data_Files/V4V5/V4V5_SILVA_taxonomy.csv")
taxonomy68 <- read.csv("G:/Desktop/Folders/Edu/2] EAS/Thesis/Real_Content/Data_Files/V6V8/taxonomy_SILVA_V6V8.csv")

head(taxonomy45)
#make a data.table
taxonomy45<-as.data.table(taxonomy45)
taxonomy68<-as.data.table(taxonomy68)
taxonomy45
taxonomy68

###read in otu table
otu45<- read.csv("G:/Desktop/Folders/Edu/2] EAS/Thesis/Real_Content/Data_Files/V4V5/V4V5__ASV_table.csv", header = T) #,row.names=1
otu68<- read.csv("G:/Desktop/Folders/Edu/2] EAS/Thesis/Real_Content/Data_Files/V6V8/V6V8__ASV_table.csv", header = T)
head(otu45) 
head(otu68)

#Convert to long format
otu_long45<-gather(otu45, Sample, Counts, "X122":"X83") #dashes got changed to dots for some reason
otu_long68<-gather(otu68, Sample, Counts, "X122.o":"X83.o") #dashes got changed to dots for some reason

#make a data. Table
otu_long45<-as.data.table(otu_long45)
otu_long68<-as.data.table(otu_long68)
otu_long45
otu_long68

###read in metadata file
metaD45<-read.csv("G:/Desktop/Folders/Edu/2] EAS/Thesis/Real_Content/Data_Files/V4V5/metadata_16S_V4V5_jonesSound2019.txt", sep = "")
metaD45<-as.data.table(metaD45)
metaD45$Sample<-as.character(metaD45$Sample)
metaD45

metaD68<-read.csv("G:/Desktop/Folders/Edu/2] EAS/Thesis/Real_Content/Data_Files/V6V8/metadata_16S_V6V8_jonesSound2019.txt", sep = "")
metaD68<-as.data.table(metaD68)
metaD68$Sample<-as.character(metaD68$Sample)
metaD68


# first set the keys to the common column:
setkey(otu_long68,Sample)
setkey(metaD68,Sample) 

setkey(otu_long45,Sample)
setkey(metaD45,Sample) 

# join the tables
total1_45 <- merge(otu_long45,metaD45,by="Sample")
total1_45

total1_68 <- merge(otu_long68,metaD68,by="Sample")
total1_68

#set key of total1_45 as the OTUID to join the taxonomy table
setkey(total1_45,OTUID)
setkey(taxonomy45,OTUID)

setkey(total1_68,OTUID)
setkey(taxonomy68,OTUID)

#merge to big table
total2_45 <- merge(total1_45,taxonomy45)
setkey(total2_45, Sample)
total2_45

total2_68 <- merge(total1_68,taxonomy68)
setkey(total2_68, Sample)
total2_68

#Final Joined table of SILVA
all_joined_SILVA45 <- metaD45[total2_45]
(all_joined_SILVA45)

all_joined_SILVA68 <- metaD68[total2_68]
(all_joined_SILVA68)




# Join table for Greengenes ####################################

#made above
otu_long45
otu_long68
metaD45
metaD68
total1_45
total1_68

taxonomyGG45 <- read.csv("G:/Desktop/Folders/Edu/2] EAS/Thesis/Real_Content/Data_Files/V4V5/taxonomy_greengenes_V4V5.csv")
taxonomyGG68 <- read.csv("G:/Desktop/Folders/Edu/2] EAS/Thesis/Real_Content/Data_Files/V6V8/taxonomy_greengenes_V6V8.csv")
taxonomyGG45 <- as.data.table(taxonomyGG45)
taxonomyGG68 <- as.data.table(taxonomyGG68)

setkey(taxonomyGG68,OTUID)
setkey(taxonomyGG45,OTUID)

total2_GG45 <- merge(total1_45,taxonomyGG45)
setkey(total2_GG45, Sample)
total2_GG45

total2_GG68 <- merge(total1_68,taxonomyGG68)
setkey(total2_GG68, Sample)
total2_GG68

#Final Joined table of GreenGenes
all_joined_GG45 <- metaD45[total2_GG45]
(all_joined_GG45)

all_joined_GG68 <- metaD68[total2_GG68]
(all_joined_GG68)





# Join table for RDP ####################################

#made above
otu_long45
otu_long68
metaD45
metaD68
total1_45
total1_68

taxonomyRDP45 <- read.csv("G:/Desktop/Folders/Edu/2] EAS/Thesis/Real_Content/Data_Files/V4V5/taxonomy_RDP_V4V5.csv")
taxonomyRDP68 <- read.csv("G:/Desktop/Folders/Edu/2] EAS/Thesis/Real_Content/Data_Files/V6V8/taxonomy_RDP_V6V8.csv")
taxonomyRDP45 <- as.data.table(taxonomyRDP45)
taxonomyRDP68 <- as.data.table(taxonomyRDP68)

setkey(taxonomyRDP68,OTUID)
setkey(taxonomyRDP45,OTUID)

total2_RDP45 <- merge(total1_45,taxonomyRDP45)
setkey(total2_RDP45, Sample)
total2_RDP45

total2_RDP68 <- merge(total1_68,taxonomyRDP68)
setkey(total2_RDP68, Sample)
total2_RDP68

#Final Joined table of GreenGenes
all_joined_RDP45 <- metaD45[total2_RDP45]
(all_joined_RDP45)

all_joined_RDP68 <- metaD68[total2_RDP68]
(all_joined_RDP68)
NA
NA
NA
NA

#####Proportion plot for each sample with both primer, based on phylum (?) ######
p45 <- ggplot(all_joined_SILVA45, aes(x = Counts, y = Sample, fill = Phylum)) + geom_bar(position = "fill", stat = "identity")
Error in ggplot(all_joined_SILVA45, aes(x = Counts, y = Sample, fill = Phylum)) : 
  could not find function "ggplot"
  
######TABLE 1: table of prevalence of bacterial counts according to each primer#####
#bacteria on x, count on y, two different graphs or two coloured bars on each graph

otu_tax_45 <- merge(otu_long45,taxonomy45,by="OTUID")
otu_tax_45

otu_tax_68 <- merge(otu_long68,taxonomy68,by="OTUID")
otu_tax_68

# Basic barplot
p<-ggplot(data = otu_tax_45, aes(y=Phylum, x=Counts/1000)) +
  geom_bar(stat="identity",position = position_dodge(width=1.5))
p



plot2 <- ggplot(NULL, aes(y=Phylum, x=Counts/1000)) + 
      geom_bar(data = otu_tax_45, stat = "identity", colour="red",width=0.4, position = position_dodge(width=0.5)) +
      geom_bar(data = otu_tax_68, stat = "identity", colour="blue",width=0.4, position = position_dodge(width=0.5))
plot2


all_joined_SILVA45

all_joined_SILVA68

### V4V5 ###
orderCount45<- select(all_joined_SILVA45, Order, Counts) #count by Order.
orderCount45<- orderCount45[order(orderCount45$Counts)]

chloroTable45 <- filter(orderCount45, Order == "Chloroplast") #Select only rows that are chloroplasts
chloroSum45 <- sum(chloroTable45$Counts)
chloroSum45 #this is the number of sequences associated with chloroplasts by V4V5
[1] 78158
### V6V8 ###
orderCount68<- select(all_joined_SILVA68, Order, Counts) #count by Order.
orderCount68<- orderCount68[order(orderCount68$Counts)]

chloroTable68 <- filter(orderCount68, Order == "Chloroplast") #Select only rows that are chloroplasts
chloroSum68 <- sum(chloroTable68$Counts)
chloroSum68 #this is the number of sequences associated with chloroplasts by V4V5
[1] 57941
#TODO
#Counts of archaea members SILVA

#Database like commands for tables!!!
#https://stackoverflow.com/questions/12353820/sort-rows-in-data-table-in-decreasing-order-on-string-key-order-x-v-gives-er

#For V4V5
all_joined_SILVA45
sortTable45 <- all_joined_SILVA45[order(rank(Kingdom),Phylum)] #sort by kingdom name
Archaeas45 <- filter(sortTable45, Kingdom == "Archaea") #Select only rows where Kingdom is Archaea.
Archaeas45

#Simple bar graph
archPerSample45 <-ggplot(Archaeas, aes(x=Counts, y=Sample)) +
  geom_bar(stat="identity") +
  theme_light()
archPerSample45


#For V6V8
all_joined_SILVA68
sortTable68 <- all_joined_SILVA68[order(rank(Kingdom),Phylum)] #sort by kingdom name
Archaeas68 <- filter(sortTable68, Kingdom == "Archaea") #Select only rows where Kingdom is Archaea.
Archaeas68

#Simple bar graph
archPerSample68 <-ggplot(Archaeas68, aes(x=Counts, y=Sample)) +
  geom_bar(stat="identity") +
  theme_light()
archPerSample68

orderNames_S68 <- c("Nitrosopumilales")
orderSums_S68 <- c() #sums of each of the orders

#loop to find the sums of each order and add to the vector
for (oName in orderNames_S68) {
  curOrderTable <- filter(SILVA_table68, Order == oName) #Select only rows with the current order name from the full table
  curOrderTable <- select(curOrderTable, Order, Counts) #makes a sub table of only the current table's order name and counts
  
  curOrderSum <- sum(curOrderTable$Counts) #sums all the counts of that order
  orderSums_S68 <- c(orderSums_S68, curOrderSum) 
}
(orderSums_S68)
[1] 8226
orderDataFrame_S68 <- data.frame(orderNames_S68, orderSums_S68)
orderDataFrame_S68

topArchGraph_S68 <-ggplot(orderDataFrame_S68, aes(x=orderSums_S68, y=orderNames_S68)) +
  geom_bar(stat="identity") +
  theme_light()
topArchGraph_S68

#TODO
#Phyloseq to get alpha diversity
library(phyloseq)

otu_mat<- read.csv("G:/Desktop/Folders/Edu/2] EAS/Thesis/Real_Content/Data_Files/V4V5/V4V5__ASV_table.csv", header = T, row.names = 1) #,row.names=1
tax_mat <-  read.csv("G:/Desktop/Folders/Edu/2] EAS/Thesis/Real_Content/Data_Files/V4V5/V4V5_SILVA_taxonomy.csv", header = T, row.names = 1)
samples_df<-read.csv("G:/Desktop/Folders/Edu/2] EAS/Thesis/Real_Content/Data_Files/V4V5/metadata_16S_V4V5_jonesSound2019.txt", sep = "")

head(tax_mat)
head(otu_mat)

#assign row names
row.names(otu_mat) <- otu_mat$OTUID
#row.names(tax_mat) <- tax_mat$OTUID
#row.names(samples_df) <- samples_df$Site

#Transform into matrixes otu and tax tables (sample table can be left as data frame)
otu_mat <- as.matrix(otu_mat)
#tax_mat <- as.matrix(tax_mat)

class(tax_mat)

#Transform to phyloseq objects
class(otu_mat) <- "numeric" #NEED to convert to numeric in this way. Have to run whole chunk.

OTU = otu_table(otu_mat, taxa_are_rows = TRUE)
TAX = tax_table(tax_mat)
samples = sample_data(samples_df)

head(OTU)
head(TAX)

#taxa_names(OTU)
sample_names(OTU)
sample_names(TAX)

taxa_names(OTU)
taxa_names(TAX)

#Convert phyloseq
Perma <- phyloseq(OTU, TAX, samples)
Perma
#Making Bubble plots (TODO)

#V4V5 -----------------------------------------------------------------------------------------------------------------

###read in otu table of V4V5
otu45<- read.csv("G:/Desktop/Folders/Edu/2] EAS/Thesis/Real_Content/Data_Files/V4V5/V4V5__ASV_table.csv") #,row.names=1
head(otu45) 
#Convert to long format
otu_long45<-gather(otu45, Sample, Counts, "X122":"X83") #dashes got changed to dots for some reason
#make a data. Table
otu_long45<-as.data.table(otu_long45)
otu_long45

###read in V4V5_SILVA_taxonomy.csv
taxonomy45 <- read.csv("G:/Desktop/Folders/Edu/2] EAS/Thesis/Real_Content/Data_Files/V4V5/V4V5_SILVA_taxonomy.csv")
head(taxonomy45)
#make a data.table
taxonomy45<-as.data.table(taxonomy45)
taxonomy45

###read in metadata file
metaD45<-read.csv2("G:/Desktop/Folders/Edu/2] EAS/Thesis/Real_Content/Data_Files/V4V5/metadata_16S_V4V5_jonesSound2019.txt")
metaD45<-as.data.table(metaD45)
head(metaD45)


write.csv(otu_long45, "G:/Desktop/Folders/Edu/2] EAS/Thesis/Real_Content/Data_Files/V4V5/for_plot45.csv")
#remove 0s
for_plot45 <- filter(otu_long45, Counts!= 0)
#for relative abundance:
#change "Name" for the name of your column with group description
for_plot45$type<-as.factor(for_plot45$type)
#order
for_plot45$type<-factor(for_plot45$type, levels=c( "river", "natural biofilm", "artificial biofilm"))
#Now order your x axis (site names) <-- edit accordingly.
for_plot45$Site <- factor(for_plot45$Site, levels = c( "Sif_1","SI_2","SI_3", "S4_1", "Big_1", "BH_2", "BH_3", "Ram_1","RAM_3", "Bapt_1", "BP_2", "BP_3", "Nord_1", "N_2", "N_3", "Rose_1", "RMS_1", "RMS_2", "RM_3", "MM_1", "Mod_1", "MM_2", "MM_3", "TM_1", "T_2", "SM_2", "White_1", "WM_2", "WM_3", "GM_1", "Sturg_1", "ST_2", "Verm_1", "VM_1", "VA_1", "VM_2", "VM_3", "V3_1"))

#sweet- now plot (note that this is for raw counts; change for relative abundance)
theme_set(theme_bw())
col=c( "green","orange", "purple")## <- change accordingly, if desired-- see http://www.stat.columbia.edu/~tzheng/files/Rcolor.pdf
g <- ggplot(for_plot45, aes(x=Sample, y=Sample)) 
g + geom_point(aes(size=Counts)) +
  scale_colour_manual(values=col)+
  theme(axis.text.x = element_text(angle = 45, hjust = 1, size=9))+
  theme(axis.text.y = element_text( size=9))+
  theme(axis.title.x=element_text(size=12))+
  theme(axis.title.y=element_text(size=12))
#export both bubble plots as PDF.


#V6V8 -----------------------------------------------------------------------------------------------------------------

###read in otu table of V6V8 
otu68<- read.csv("G:/Desktop/Folders/Edu/2] EAS/Thesis/Real_Content/Data_Files/V6V8/V6V8__ASV_table.csv") #,row.names=1
head(otu68) 
#Convert to long format
otu_long68<-gather(otu68, Sample, Counts, "X122.o":"X83.o") #dashes got changed to dots for some reason
#make a data. Table
otu_long68<-as.data.table(otu_long68)
otu_long68

###read in biom-taxonomy
taxonomy68 <- read.csv("G:/Desktop/Folders/Edu/2] EAS/Thesis/Real_Content/Data_Files/V6V8/taxonomy_SILVA_V6V8.csv")
head(taxonomy68)
#make a data.table
taxonomy<-as.data.table(taxonomy68)
taxonomy68

###read in metadata file
metaD68<-read.csv2("G:/Desktop/Folders/Edu/2] EAS/Thesis/Real_Content/Data_Files/V6V8/metadata_16S_V6V8_jonesSound2019C.csv") 
metaD68<-as.data.table(metaD68)
head(metaD68)



write.csv(otu_long68,"G:/Desktop/Folders/Edu/2] EAS/Thesis/Real_Content/Data_Files/V6V8/for_plot68.csv")
v68 <- read.csv("G:/Desktop/Folders/Edu/2] EAS/Thesis/Real_Content/Data_Files/V6V8/for_plot68.csv")
v68

#remove 0s
for_plot68 <- filter(otu_long68, Counts!= 0)
#for relative abundance:
#change "Name" for the name of your column with group description
for_plot68$type<-as.factor(for_plot68$type)
#order
for_plot68$type<-factor(for_plot68$type, levels=c( "river", "natural biofilm", "artificial biofilm"))
#Now order your x axis (site names) <-- edit accordingly.
for_plot68$Site <- factor(for_plot68$Site, levels = c( "Sif_1","SI_2","SI_3", "S4_1", "Big_1", "BH_2", "BH_3", "Ram_1","RAM_3", "Bapt_1", "BP_2", "BP_3", "Nord_1", "N_2", "N_3", "Rose_1", "RMS_1", "RMS_2", "RM_3", "MM_1", "Mod_1", "MM_2", "MM_3", "TM_1", "T_2", "SM_2", "White_1", "WM_2", "WM_3", "GM_1", "Sturg_1", "ST_2", "Verm_1", "VM_1", "VA_1", "VM_2", "VM_3", "V3_1"))

#sweet- now plot (note that this is for raw counts; change for relative abundance)
theme_set(theme_bw())
col=c( "green","orange", "purple")## <- change accordingly, if desired-- see http://www.stat.columbia.edu/~tzheng/files/Rcolor.pdf
g <- ggplot(for_plot68, aes(x=Sample, y=Sample))#colour=type
g + geom_point(aes(size=Counts)) +
  scale_colour_manual(values=col)+
  theme(axis.text.x = element_text(angle = 45, hjust = 1, size=9))+
  theme(axis.text.y = element_text( size=9))+
  theme(axis.title.x=element_text(size=12))+
  theme(axis.title.y=element_text(size=12))
#export both bubble plots as PDF.

#Data processing with Pyloseq:https://vaulot.github.io/tutorials/Phyloseq_tutorial.html


otu_mat <-read.csv("G:/Desktop/Folders/Edu/2] EAS/Thesis/Example_Content/all_OTU_NMDSnu.csv", row.names=1) 
tax_mat <- read.csv("G:/Desktop/Folders/Edu/2] EAS/Thesis/Example_Content/biom-taxonomy.csv", row.names=1)
samples_df  <- as.data.frame(read.csv("G:/Desktop/Folders/Edu/2] EAS/Thesis/Example_Content/all_OTU_NMDS.csv"))

head(otu_mat)
head(samples_df)

#assign row names
row.names(otu_mat) <- otu_mat$OTUID
row.names(tax_mat) <- tax_mat$OTUID
row.names(samples_df) <- samples_df$Site

#Transform into matrixes otu and tax tables (sample table can be left as data frame)
otu_mat <- as.matrix(otu_mat)
tax_mat <- as.matrix(tax_mat)

class(otu_mat)

#Transform to phyloseq objects
class(otu_mat) <- "numeric" #NEED to convert to numeric in this way. Have to run whole chunk.

OTU = otu_table(otu_mat, taxa_are_rows = TRUE)
TAX = tax_table(a)
samples = sample_data(samples_df)

nrow(OTU)
nrow(TAX)
nrow(samples)

#Convert phyloseq
Perma <- phyloseq(OTU, TAX, samples)
Perma
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpUaGlzIGlzIGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLiANCg0KQWRkIGEgbmV3IGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqSW5zZXJ0IENodW5rKiBidXR0b24gb24gdGhlIHRvb2xiYXIgb3IgYnkgcHJlc3NpbmcgKkN0cmwrQWx0K0kqLg0KDQpXaGVuIHlvdSBzYXZlIHRoZSBub3RlYm9vaywgYW4gSFRNTCBmaWxlIGNvbnRhaW5pbmcgdGhlIGNvZGUgYW5kIG91dHB1dCB3aWxsIGJlIHNhdmVkIGFsb25nc2lkZSBpdCAoY2xpY2sgdGhlICpQcmV2aWV3KiBidXR0b24gb3IgcHJlc3MgKkN0cmwrU2hpZnQrSyogdG8gcHJldmlldyB0aGUgSFRNTCBmaWxlKS4NCg0KVGhlIHByZXZpZXcgc2hvd3MgeW91IGEgcmVuZGVyZWQgSFRNTCBjb3B5IG9mIHRoZSBjb250ZW50cyBvZiB0aGUgZWRpdG9yLiBDb25zZXF1ZW50bHksIHVubGlrZSAqS25pdCosICpQcmV2aWV3KiBkb2VzIG5vdCBydW4gYW55IFIgY29kZSBjaHVua3MuIEluc3RlYWQsIHRoZSBvdXRwdXQgb2YgdGhlIGNodW5rIHdoZW4gaXQgd2FzIGxhc3QgcnVuIGluIHRoZSBlZGl0b3IgaXMgZGlzcGxheWVkLg0KDQoNCmBgYHtyfQ0KI0luc3RhbGwgcGFja2FnZXMNCg0KaW5zdGFsbC5wYWNrYWdlcygiQmlvY01hbmFnZXIiKQ0KQmlvY01hbmFnZXI6Omluc3RhbGwoImRhZGEyIiwgdmVyc2lvbiA9ICIzLjExIikNCg0KaW5zdGFsbC5wYWNrYWdlcygicWlpbWUyUiIpDQppbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQ0KaW5zdGFsbC5wYWNrYWdlcygiYmlvbWZvcm1hdCIpDQppbnN0YWxsLnBhY2thZ2VzKCd2ZWdhbicpDQppbnN0YWxsLnBhY2thZ2VzKCdyZWFkcicpDQogDQpgYGANCg0KYGBge3J9DQojTG9hZCBwYWNrYWdlcw0KDQpsaWJyYXJ5KCJ0aWR5dmVyc2UiKQ0KbGlicmFyeSgiZGFkYTIiKQ0KbGlicmFyeSgiYmlvbWZvcm1hdCIpDQpsaWJyYXJ5KCd2ZWdhbicpDQpsaWJyYXJ5KCdyZWFkcicpDQpsaWJyYXJ5KCJkcGx5ciIpICAgICAjIFRvIG1hbmlwdWxhdGUgZGF0YWZyYW1lcw0KbGlicmFyeSgicmVhZHhsIikgICAgIyBUbyByZWFkIEV4Y2VsIGZpbGVzIGludG8gUg0KbGlicmFyeSgiZ2dwbG90MiIpICAgIyBmb3IgaGlnaCBxdWFsaXR5IGdyYXBoaWNzDQpsaWJyYXJ5KCJCaW9jTWFuYWdlciIpDQpsaWJyYXJ5KCJwaHlsb3NlcSIpICAgDQpsaWJyYXJ5KCJ0aWR5ciIpDQpsaWJyYXJ5KCJkYXRhLnRhYmxlIikNCmBgYA0KDQoNCg0KYGBge3J9DQojTWVyZ2luZyB0YWJsZXMgZm9yIHNwZWNpZXMgYWJ1bmRhbmNlIDENCiNodHRwOi8vd3d3LmNvb2tib29rLXIuY29tL01hbmlwdWxhdGluZ19kYXRhL0NvbnZlcnRpbmdfZGF0YV9iZXR3ZWVuX3dpZGVfYW5kX2xvbmdfZm9ybWF0Lw0KDQoNCg0KIyMjcmVhZCBpbiBTSUxWQSBiaW9tLXRheG9ub215IGZvciBTSUxWQSAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQoNCnRheG9ub215NDUgPC0gcmVhZC5jc3YoIkc6L0Rlc2t0b3AvRm9sZGVycy9FZHUvMl0gRUFTL1RoZXNpcy9SZWFsX0NvbnRlbnQvRGF0YV9GaWxlcy9WNFY1L1Y0VjVfU0lMVkFfdGF4b25vbXkuY3N2IikNCnRheG9ub215NjggPC0gcmVhZC5jc3YoIkc6L0Rlc2t0b3AvRm9sZGVycy9FZHUvMl0gRUFTL1RoZXNpcy9SZWFsX0NvbnRlbnQvRGF0YV9GaWxlcy9WNlY4L3RheG9ub215X1NJTFZBX1Y2VjguY3N2IikNCg0KaGVhZCh0YXhvbm9teTQ1KQ0KI21ha2UgYSBkYXRhLnRhYmxlDQp0YXhvbm9teTQ1PC1hcy5kYXRhLnRhYmxlKHRheG9ub215NDUpDQp0YXhvbm9teTY4PC1hcy5kYXRhLnRhYmxlKHRheG9ub215NjgpDQp0YXhvbm9teTQ1DQp0YXhvbm9teTY4DQoNCiMjI3JlYWQgaW4gb3R1IHRhYmxlDQpvdHU0NTwtIHJlYWQuY3N2KCJHOi9EZXNrdG9wL0ZvbGRlcnMvRWR1LzJdIEVBUy9UaGVzaXMvUmVhbF9Db250ZW50L0RhdGFfRmlsZXMvVjRWNS9WNFY1X19BU1ZfdGFibGUuY3N2IiwgaGVhZGVyID0gVCkgIyxyb3cubmFtZXM9MQ0Kb3R1Njg8LSByZWFkLmNzdigiRzovRGVza3RvcC9Gb2xkZXJzL0VkdS8yXSBFQVMvVGhlc2lzL1JlYWxfQ29udGVudC9EYXRhX0ZpbGVzL1Y2VjgvVjZWOF9fQVNWX3RhYmxlLmNzdiIsIGhlYWRlciA9IFQpDQpoZWFkKG90dTQ1KSANCmhlYWQob3R1NjgpDQoNCiNDb252ZXJ0IHRvIGxvbmcgZm9ybWF0DQpvdHVfbG9uZzQ1PC1nYXRoZXIob3R1NDUsIFNhbXBsZSwgQ291bnRzLCAiWDEyMiI6Ilg4MyIpICNkYXNoZXMgZ290IGNoYW5nZWQgdG8gZG90cyBmb3Igc29tZSByZWFzb24NCm90dV9sb25nNjg8LWdhdGhlcihvdHU2OCwgU2FtcGxlLCBDb3VudHMsICJYMTIyLm8iOiJYODMubyIpICNkYXNoZXMgZ290IGNoYW5nZWQgdG8gZG90cyBmb3Igc29tZSByZWFzb24NCg0KI21ha2UgYSBkYXRhLiBUYWJsZQ0Kb3R1X2xvbmc0NTwtYXMuZGF0YS50YWJsZShvdHVfbG9uZzQ1KQ0Kb3R1X2xvbmc2ODwtYXMuZGF0YS50YWJsZShvdHVfbG9uZzY4KQ0Kb3R1X2xvbmc0NQ0Kb3R1X2xvbmc2OA0KDQojIyNyZWFkIGluIG1ldGFkYXRhIGZpbGUNCm1ldGFENDU8LXJlYWQuY3N2KCJHOi9EZXNrdG9wL0ZvbGRlcnMvRWR1LzJdIEVBUy9UaGVzaXMvUmVhbF9Db250ZW50L0RhdGFfRmlsZXMvVjRWNS9tZXRhZGF0YV8xNlNfVjRWNV9qb25lc1NvdW5kMjAxOS50eHQiLCBzZXAgPSAiIikNCm1ldGFENDU8LWFzLmRhdGEudGFibGUobWV0YUQ0NSkNCm1ldGFENDUkU2FtcGxlPC1hcy5jaGFyYWN0ZXIobWV0YUQ0NSRTYW1wbGUpDQptZXRhRDQ1DQoNCm1ldGFENjg8LXJlYWQuY3N2KCJHOi9EZXNrdG9wL0ZvbGRlcnMvRWR1LzJdIEVBUy9UaGVzaXMvUmVhbF9Db250ZW50L0RhdGFfRmlsZXMvVjZWOC9tZXRhZGF0YV8xNlNfVjZWOF9qb25lc1NvdW5kMjAxOS50eHQiLCBzZXAgPSAiIikNCm1ldGFENjg8LWFzLmRhdGEudGFibGUobWV0YUQ2OCkNCm1ldGFENjgkU2FtcGxlPC1hcy5jaGFyYWN0ZXIobWV0YUQ2OCRTYW1wbGUpDQptZXRhRDY4DQoNCg0KIyBmaXJzdCBzZXQgdGhlIGtleXMgdG8gdGhlIGNvbW1vbiBjb2x1bW46DQpzZXRrZXkob3R1X2xvbmc2OCxTYW1wbGUpDQpzZXRrZXkobWV0YUQ2OCxTYW1wbGUpIA0KDQpzZXRrZXkob3R1X2xvbmc0NSxTYW1wbGUpDQpzZXRrZXkobWV0YUQ0NSxTYW1wbGUpIA0KDQojIGpvaW4gdGhlIHRhYmxlcw0KdG90YWwxXzQ1IDwtIG1lcmdlKG90dV9sb25nNDUsbWV0YUQ0NSxieT0iU2FtcGxlIikNCnRvdGFsMV80NQ0KDQp0b3RhbDFfNjggPC0gbWVyZ2Uob3R1X2xvbmc2OCxtZXRhRDY4LGJ5PSJTYW1wbGUiKQ0KdG90YWwxXzY4DQoNCiNzZXQga2V5IG9mIHRvdGFsMV80NSBhcyB0aGUgT1RVSUQgdG8gam9pbiB0aGUgdGF4b25vbXkgdGFibGUNCnNldGtleSh0b3RhbDFfNDUsT1RVSUQpDQpzZXRrZXkodGF4b25vbXk0NSxPVFVJRCkNCg0Kc2V0a2V5KHRvdGFsMV82OCxPVFVJRCkNCnNldGtleSh0YXhvbm9teTY4LE9UVUlEKQ0KDQojbWVyZ2UgdG8gYmlnIHRhYmxlDQp0b3RhbDJfNDUgPC0gbWVyZ2UodG90YWwxXzQ1LHRheG9ub215NDUpDQpzZXRrZXkodG90YWwyXzQ1LCBTYW1wbGUpDQp0b3RhbDJfNDUNCg0KdG90YWwyXzY4IDwtIG1lcmdlKHRvdGFsMV82OCx0YXhvbm9teTY4KQ0Kc2V0a2V5KHRvdGFsMl82OCwgU2FtcGxlKQ0KdG90YWwyXzY4DQoNCiNGaW5hbCBKb2luZWQgdGFibGUgb2YgU0lMVkENCmFsbF9qb2luZWRfU0lMVkE0NSA8LSBtZXRhRDQ1W3RvdGFsMl80NV0NCihhbGxfam9pbmVkX1NJTFZBNDUpDQoNCmFsbF9qb2luZWRfU0lMVkE2OCA8LSBtZXRhRDY4W3RvdGFsMl82OF0NCihhbGxfam9pbmVkX1NJTFZBNjgpDQoNCg0KDQoNCiMgSm9pbiB0YWJsZSBmb3IgR3JlZW5nZW5lcyAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCg0KI21hZGUgYWJvdmUNCm90dV9sb25nNDUNCm90dV9sb25nNjgNCm1ldGFENDUNCm1ldGFENjgNCnRvdGFsMV80NQ0KdG90YWwxXzY4DQoNCnRheG9ub215R0c0NSA8LSByZWFkLmNzdigiRzovRGVza3RvcC9Gb2xkZXJzL0VkdS8yXSBFQVMvVGhlc2lzL1JlYWxfQ29udGVudC9EYXRhX0ZpbGVzL1Y0VjUvdGF4b25vbXlfZ3JlZW5nZW5lc19WNFY1LmNzdiIpDQp0YXhvbm9teUdHNjggPC0gcmVhZC5jc3YoIkc6L0Rlc2t0b3AvRm9sZGVycy9FZHUvMl0gRUFTL1RoZXNpcy9SZWFsX0NvbnRlbnQvRGF0YV9GaWxlcy9WNlY4L3RheG9ub215X2dyZWVuZ2VuZXNfVjZWOC5jc3YiKQ0KdGF4b25vbXlHRzQ1IDwtIGFzLmRhdGEudGFibGUodGF4b25vbXlHRzQ1KQ0KdGF4b25vbXlHRzY4IDwtIGFzLmRhdGEudGFibGUodGF4b25vbXlHRzY4KQ0KDQpzZXRrZXkodGF4b25vbXlHRzY4LE9UVUlEKQ0Kc2V0a2V5KHRheG9ub215R0c0NSxPVFVJRCkNCg0KdG90YWwyX0dHNDUgPC0gbWVyZ2UodG90YWwxXzQ1LHRheG9ub215R0c0NSkNCnNldGtleSh0b3RhbDJfR0c0NSwgU2FtcGxlKQ0KdG90YWwyX0dHNDUNCg0KdG90YWwyX0dHNjggPC0gbWVyZ2UodG90YWwxXzY4LHRheG9ub215R0c2OCkNCnNldGtleSh0b3RhbDJfR0c2OCwgU2FtcGxlKQ0KdG90YWwyX0dHNjgNCg0KI0ZpbmFsIEpvaW5lZCB0YWJsZSBvZiBHcmVlbkdlbmVzDQphbGxfam9pbmVkX0dHNDUgPC0gbWV0YUQ0NVt0b3RhbDJfR0c0NV0NCihhbGxfam9pbmVkX0dHNDUpDQoNCmFsbF9qb2luZWRfR0c2OCA8LSBtZXRhRDY4W3RvdGFsMl9HRzY4XQ0KKGFsbF9qb2luZWRfR0c2OCkNCg0KDQoNCg0KDQojIEpvaW4gdGFibGUgZm9yIFJEUCAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCg0KI21hZGUgYWJvdmUNCm90dV9sb25nNDUNCm90dV9sb25nNjgNCm1ldGFENDUNCm1ldGFENjgNCnRvdGFsMV80NQ0KdG90YWwxXzY4DQoNCnRheG9ub215UkRQNDUgPC0gcmVhZC5jc3YoIkc6L0Rlc2t0b3AvRm9sZGVycy9FZHUvMl0gRUFTL1RoZXNpcy9SZWFsX0NvbnRlbnQvRGF0YV9GaWxlcy9WNFY1L3RheG9ub215X1JEUF9WNFY1LmNzdiIpDQp0YXhvbm9teVJEUDY4IDwtIHJlYWQuY3N2KCJHOi9EZXNrdG9wL0ZvbGRlcnMvRWR1LzJdIEVBUy9UaGVzaXMvUmVhbF9Db250ZW50L0RhdGFfRmlsZXMvVjZWOC90YXhvbm9teV9SRFBfVjZWOC5jc3YiKQ0KdGF4b25vbXlSRFA0NSA8LSBhcy5kYXRhLnRhYmxlKHRheG9ub215UkRQNDUpDQp0YXhvbm9teVJEUDY4IDwtIGFzLmRhdGEudGFibGUodGF4b25vbXlSRFA2OCkNCg0Kc2V0a2V5KHRheG9ub215UkRQNjgsT1RVSUQpDQpzZXRrZXkodGF4b25vbXlSRFA0NSxPVFVJRCkNCg0KdG90YWwyX1JEUDQ1IDwtIG1lcmdlKHRvdGFsMV80NSx0YXhvbm9teVJEUDQ1KQ0Kc2V0a2V5KHRvdGFsMl9SRFA0NSwgU2FtcGxlKQ0KdG90YWwyX1JEUDQ1DQoNCnRvdGFsMl9SRFA2OCA8LSBtZXJnZSh0b3RhbDFfNjgsdGF4b25vbXlSRFA2OCkNCnNldGtleSh0b3RhbDJfUkRQNjgsIFNhbXBsZSkNCnRvdGFsMl9SRFA2OA0KDQojRmluYWwgSm9pbmVkIHRhYmxlIG9mIEdyZWVuR2VuZXMNCmFsbF9qb2luZWRfUkRQNDUgPC0gbWV0YUQ0NVt0b3RhbDJfUkRQNDVdDQooYWxsX2pvaW5lZF9SRFA0NSkNCg0KYWxsX2pvaW5lZF9SRFA2OCA8LSBtZXRhRDY4W3RvdGFsMl9SRFA2OF0NCihhbGxfam9pbmVkX1JEUDY4KQ0KDQoNCg0KDQpgYGANCg0KDQpgYGB7cn0NCg0KIyMjIyNQcm9wb3J0aW9uIHBsb3QgZm9yIGVhY2ggc2FtcGxlIHdpdGggYm90aCBwcmltZXIsIGJhc2VkIG9uIHBoeWx1bSAoPykgIyMjIyMjDQpwNDUgPC0gZ2dwbG90KGFsbF9qb2luZWRfU0lMVkE0NSwgYWVzKHggPSBDb3VudHMsIHkgPSBTYW1wbGUsIGZpbGwgPSBQaHlsdW0pKSArIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiLCBzdGF0ID0gImlkZW50aXR5IikNCmdncGxvdChvdHVfbG9uZ04sIGFlcyhmaWxsPUNvdW50cywgeT0xLCB4PTEpKSArIA0KICAgIGdlb21fYmFyKHBvc2l0aW9uPSJmaWxsIiwgc3RhdD0iaWRlbnRpdHkiKSArIGV4cGFuZF9saW1pdHMoeSA9IDkwMDAwMDAsIHg9LTk5OTk5OTkpICAjIG9yIHNvbWUgb3RoZXIgYXJiaXRyYXJpbHkgbGFyZ2UgbnVtYmVyDQpwNDUNCg0KDQpwNjggPC0gZ2dwbG90KGFsbF9qb2luZWRfU0lMVkE2OCwgYWVzKHggPSBDb3VudHMsIHkgPSBTYW1wbGUsIGZpbGwgPSBQaHlsdW0pKSArIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiLCBzdGF0ID0gImlkZW50aXR5IikNCmdncGxvdChvdHVfbG9uZ04sIGFlcyhmaWxsPUNvdW50cywgeT0xLCB4PTEpKSArIA0KICAgIGdlb21fYmFyKHBvc2l0aW9uPSJmaWxsIiwgc3RhdD0iaWRlbnRpdHkiKSArIGV4cGFuZF9saW1pdHMoeSA9IDkwMDAwMDAsIHg9LTk5OTk5OTkpICAjIG9yIHNvbWUgb3RoZXIgYXJiaXRyYXJpbHkgbGFyZ2UgbnVtYmVyDQpwNjgNCiAgDQpgYGANCg0KDQoNCmBgYHtyfQ0KICANCiMjIyMjI1RBQkxFIDE6IHRhYmxlIG9mIHByZXZhbGVuY2Ugb2YgYmFjdGVyaWFsIGNvdW50cyBhY2NvcmRpbmcgdG8gZWFjaCBwcmltZXIjIyMjIw0KI2JhY3RlcmlhIG9uIHgsIGNvdW50IG9uIHksIHR3byBkaWZmZXJlbnQgZ3JhcGhzIG9yIHR3byBjb2xvdXJlZCBiYXJzIG9uIGVhY2ggZ3JhcGgNCg0Kb3R1X3RheF80NSA8LSBtZXJnZShvdHVfbG9uZzQ1LHRheG9ub215NDUsYnk9Ik9UVUlEIikNCm90dV90YXhfNDUNCg0Kb3R1X3RheF82OCA8LSBtZXJnZShvdHVfbG9uZzY4LHRheG9ub215NjgsYnk9Ik9UVUlEIikNCm90dV90YXhfNjgNCg0KIyBCYXNpYyBiYXJwbG90DQpwPC1nZ3Bsb3QoZGF0YSA9IG90dV90YXhfNDUsIGFlcyh5PVBoeWx1bSwgeD1Db3VudHMvMTAwMCkpICsNCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGg9MS41KSkNCnANCg0KDQpwbG90MiA8LSBnZ3Bsb3QoTlVMTCwgYWVzKHk9UGh5bHVtLCB4PUNvdW50cy8xMDAwKSkgKyANCiAgICAgIGdlb21fYmFyKGRhdGEgPSBvdHVfdGF4XzQ1LCBzdGF0ID0gImlkZW50aXR5IiwgY29sb3VyPSJyZWQiLHdpZHRoPTAuNCwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aD0wLjUpKSArDQogICAgICBnZW9tX2JhcihkYXRhID0gb3R1X3RheF82OCwgc3RhdCA9ICJpZGVudGl0eSIsIGNvbG91cj0iYmx1ZSIsd2lkdGg9MC40LCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoPTAuNSkpDQpwbG90Mg0KYGBgDQoNCg0KYGBge3J9DQojRmluZCB0b3AgMjAgbW9zdCBhYnVuZGFudCBvcmRlcnM6DQoNCnRheG9ub215NDUNCnRheG9ub215NjgNCmFsbF9qb2luZWRfU0lMVkE0NQ0KYWxsX2pvaW5lZF9TSUxWQTY4DQoNCiNTb3J0IG91dCB0aGUgY291bnRzIG9mIE9yZGVycw0Kb3JkZXJDb3VudDQ1PC0gYXMuZGF0YS50YWJsZSh0YWJsZShhbGxfam9pbmVkX1NJTFZBNDUkT3JkZXIpKSAjY291bnQgYnkgT3JkZXIuDQpvcmRlckNvdW50NDU8LSBvcmRlckNvdW50NDVbb3JkZXIob3JkZXJDb3VudDQ1JE4pXQ0Kb3JkZXJDb3VudDQ1ICNWMSBpcyB0aGUgT3JkZXIgbmFtZSwgTiBpcyB0aGUgY291bnQuDQoNCm9yZGVyQ291bnQ2ODwtIGFzLmRhdGEudGFibGUodGFibGUoYWxsX2pvaW5lZF9TSUxWQTY4JE9yZGVyKSkgI2NvdW50IGJ5IE9yZGVyLg0Kb3JkZXJDb3VudDY4PC0gb3JkZXJDb3VudDY4W29yZGVyKG9yZGVyQ291bnQ2OCROKV0NCm9yZGVyQ291bnQ2OCAjVjEgaXMgdGhlIE9yZGVyIG5hbWUsIE4gaXMgdGhlIGNvdW50Lg0KDQojR2V0IHRvcCBPcmRlcnMNCnRvcFRheGE0NSA8LSBzbGljZV90YWlsKG9yZGVyQ291bnQ0NSwgbj0yMCkgI2dldCB0aGUgYm90dG9tIDIwIGNvdW50cyAoaXQncyBieSBhc2NlbmRpbmcgb3JkZXIpDQp0b3BUYXhhNDUNCg0KdG9wVGF4YTY4IDwtIHNsaWNlX3RhaWwob3JkZXJDb3VudDY4LG49MjApDQp0b3BUYXhhNjgNCg0KcDwtZ2dwbG90KHRvcFRheGE0NSwgYWVzKHg9TiwgeT1WMSkpICsNCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArDQogIHRoZW1lX2xpZ2h0KCkNCnANCg0KcDwtZ2dwbG90KHRvcFRheGE2OCwgYWVzKHg9TiwgeT1WMSkpICsNCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArDQogIHRoZW1lX2xpZ2h0KCkNCnANCg0KYGBgDQoNCg0KYGBge3J9DQojVEFCTEUgMzogbm8gb2Ygc2VxdWVuY2VzIGFzc29jaWF0ZWQgd2l0aCBjaGxvcm9wbGFzdHMgcGVyIHByaW1lcg0KDQphbGxfam9pbmVkX1NJTFZBNDUNCmFsbF9qb2luZWRfU0lMVkE2OA0KDQojIyMgVjRWNSAjIyMNCm9yZGVyQ291bnQ0NTwtIHNlbGVjdChhbGxfam9pbmVkX1NJTFZBNDUsIE9yZGVyLCBDb3VudHMpICNjb3VudCBieSBPcmRlci4NCm9yZGVyQ291bnQ0NTwtIG9yZGVyQ291bnQ0NVtvcmRlcihvcmRlckNvdW50NDUkQ291bnRzKV0NCg0KY2hsb3JvVGFibGU0NSA8LSBmaWx0ZXIob3JkZXJDb3VudDQ1LCBPcmRlciA9PSAiQ2hsb3JvcGxhc3QiKSAjU2VsZWN0IG9ubHkgcm93cyB0aGF0IGFyZSBjaGxvcm9wbGFzdHMNCmNobG9yb1N1bTQ1IDwtIHN1bShjaGxvcm9UYWJsZTQ1JENvdW50cykNCmNobG9yb1N1bTQ1ICN0aGlzIGlzIHRoZSBudW1iZXIgb2Ygc2VxdWVuY2VzIGFzc29jaWF0ZWQgd2l0aCBjaGxvcm9wbGFzdHMgYnkgVjRWNQ0KDQojIyMgVjZWOCAjIyMNCm9yZGVyQ291bnQ2ODwtIHNlbGVjdChhbGxfam9pbmVkX1NJTFZBNjgsIE9yZGVyLCBDb3VudHMpICNjb3VudCBieSBPcmRlci4NCm9yZGVyQ291bnQ2ODwtIG9yZGVyQ291bnQ2OFtvcmRlcihvcmRlckNvdW50NjgkQ291bnRzKV0NCg0KY2hsb3JvVGFibGU2OCA8LSBmaWx0ZXIob3JkZXJDb3VudDY4LCBPcmRlciA9PSAiQ2hsb3JvcGxhc3QiKSAjU2VsZWN0IG9ubHkgcm93cyB0aGF0IGFyZSBjaGxvcm9wbGFzdHMNCmNobG9yb1N1bTY4IDwtIHN1bShjaGxvcm9UYWJsZTY4JENvdW50cykNCmNobG9yb1N1bTY4ICN0aGlzIGlzIHRoZSBudW1iZXIgb2Ygc2VxdWVuY2VzIGFzc29jaWF0ZWQgd2l0aCBjaGxvcm9wbGFzdHMgYnkgVjRWNQ0KDQoNCg0KYGBgDQpgYGB7cn0NCiNGSUdVUkUgNzogdGF4b25vbWljIHBhbmVsIGRlbGluZWF0aW5nIHRvcCAyMCAoaWYgdGhlcmUgYXJlIHRvcCAyMCkgY2hsb3JvcGxhc3Qgb3JkZXJzIHBlciBwcmltZXIgYW5kIGRhdGFiYXNlDQoNCiMjIyBWNFY1ICMjIw0Kb3JkZXJDb3VudDQ1PC0gc2VsZWN0KGFsbF9qb2luZWRfU0lMVkE0NSwgT3JkZXIsIENsYXNzLCBDb3VudHMpICNjb3VudCBhbmQgT3JkZXIuDQpvcmRlckNvdW50NDU8LSBvcmRlckNvdW50NDVbb3JkZXIob3JkZXJDb3VudDQ1JENvdW50cyldICNzb3J0IGJ5IGNvdW50DQpjaGxvcm9UYWJsZTQ1IDwtIGZpbHRlcihvcmRlckNvdW50NDUsIE9yZGVyID09ICJDaGxvcm9wbGFzdCIpICNTZWxlY3Qgb25seSByb3dzIHRoYXQgYXJlIGNobG9yb3BsYXN0cw0KdGFpbChjaGxvcm9UYWJsZTQ1LDIwKSAjdG9wIDIwIGNvdW50cy4NCg0KIyMjIFY2VjggIyMjDQpvcmRlckNvdW50Njg8LSBzZWxlY3QoYWxsX2pvaW5lZF9TSUxWQTY4LCBPcmRlciwgQ291bnRzKSAjY291bnQgYnkgT3JkZXIuDQpvcmRlckNvdW50Njg8LSBvcmRlckNvdW50Njhbb3JkZXIob3JkZXJDb3VudDY4JENvdW50cyldDQpjaGxvcm9UYWJsZTY4IDwtIGZpbHRlcihvcmRlckNvdW50NjgsIE9yZGVyID09ICJDaGxvcm9wbGFzdCIpICNTZWxlY3Qgb25seSByb3dzIHRoYXQgYXJlIGNobG9yb3BsYXN0cw0KdGFpbChjaGxvcm9UYWJsZTY4LDIwKSAjdG9wIDIwIGNvdW50cy4NCg0KI1doYXQgYXJlIHRoZSBvcmRlciBuYW1lcz8/IFRoZXkncmUgYWxsIGp1c3QgY2FsbGVkICJjaGxvcm9wbGFzdCIuDQoNCmBgYA0KDQoNCg0KDQpgYGB7cn0NCiNUT0RPDQojQ291bnRzIG9mIGFyY2hhZWEgbWVtYmVycyBTSUxWQQ0KDQojRGF0YWJhc2UgbGlrZSBjb21tYW5kcyBmb3IgdGFibGVzISEhDQojaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTIzNTM4MjAvc29ydC1yb3dzLWluLWRhdGEtdGFibGUtaW4tZGVjcmVhc2luZy1vcmRlci1vbi1zdHJpbmcta2V5LW9yZGVyLXgtdi1naXZlcy1lcg0KDQojRm9yIFY0VjUNCmFsbF9qb2luZWRfU0lMVkE0NQ0Kc29ydFRhYmxlNDUgPC0gYWxsX2pvaW5lZF9TSUxWQTQ1W29yZGVyKHJhbmsoS2luZ2RvbSksUGh5bHVtKV0gI3NvcnQgYnkga2luZ2RvbSBuYW1lDQpBcmNoYWVhczQ1IDwtIGZpbHRlcihzb3J0VGFibGU0NSwgS2luZ2RvbSA9PSAiQXJjaGFlYSIpICNTZWxlY3Qgb25seSByb3dzIHdoZXJlIEtpbmdkb20gaXMgQXJjaGFlYS4NCkFyY2hhZWFzNDUNCg0KI1NpbXBsZSBiYXIgZ3JhcGgNCmFyY2hQZXJTYW1wbGU0NSA8LWdncGxvdChBcmNoYWVhcywgYWVzKHg9Q291bnRzLCB5PVNhbXBsZSkpICsNCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArDQogIHRoZW1lX2xpZ2h0KCkNCmFyY2hQZXJTYW1wbGU0NQ0KDQoNCiNGb3IgVjZWOA0KYWxsX2pvaW5lZF9TSUxWQTY4DQpzb3J0VGFibGU2OCA8LSBhbGxfam9pbmVkX1NJTFZBNjhbb3JkZXIocmFuayhLaW5nZG9tKSxQaHlsdW0pXSAjc29ydCBieSBraW5nZG9tIG5hbWUNCkFyY2hhZWFzNjggPC0gZmlsdGVyKHNvcnRUYWJsZTY4LCBLaW5nZG9tID09ICJBcmNoYWVhIikgI1NlbGVjdCBvbmx5IHJvd3Mgd2hlcmUgS2luZ2RvbSBpcyBBcmNoYWVhLg0KQXJjaGFlYXM2OA0KDQojU2ltcGxlIGJhciBncmFwaA0KYXJjaFBlclNhbXBsZTY4IDwtZ2dwbG90KEFyY2hhZWFzNjgsIGFlcyh4PUNvdW50cywgeT1TYW1wbGUpKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKw0KICB0aGVtZV9saWdodCgpDQphcmNoUGVyU2FtcGxlNjgNCmBgYA0KDQpgYGB7cn0NCiMgdGF4b25vbWljIGJhcnBsb3QgcGFuZWwgZGVtb25zdHJhdGluZyB0b3AgMjAgYXJjaGFlYWwgb3JkZXJzIGZvciBlYWNoIGRhdGFiYXNlDQoNCiNWNFY1IHRhYmxlcw0KU0lMVkFfdGFibGU0NSA8LSBhbGxfam9pbmVkX1NJTFZBNDVbb3JkZXIocmFuayhLaW5nZG9tKSxQaHlsdW0pXSAjc29ydCBieSBraW5nZG9tIG5hbWUNCmFyY09ubHlfUzQ1IDwtIGZpbHRlcihTSUxWQV90YWJsZTQ1LCBLaW5nZG9tID09ICJBcmNoYWVhIikgI1NlbGVjdCBvbmx5IHJvd3Mgd2hlcmUgS2luZ2RvbSBpcyBBcmNoYWVhLg0KUkRQX3RhYmxlNDUgPC0gYWxsX2pvaW5lZF9SRFA0NVtvcmRlcihyYW5rKEtpbmdkb20pLFBoeWx1bSldICNzb3J0IGJ5IGtpbmdkb20gbmFtZQ0KYXJjT25seV9SNDUgPC0gZmlsdGVyKFJEUF90YWJsZTQ1LCBLaW5nZG9tID09ICJBcmNoYWVhIikgI1NlbGVjdCBvbmx5IHJvd3Mgd2hlcmUgS2luZ2RvbSBpcyBBcmNoYWVhLg0KUkRQX3RhYmxlNDUNCmFyY09ubHlfUzQ1DQoNCiNWNlY4IHRhYmxlcw0KU0lMVkFfdGFibGU2OCA8LSBhbGxfam9pbmVkX1NJTFZBNjhbb3JkZXIocmFuayhLaW5nZG9tKSxQaHlsdW0pXSAjc29ydCBieSBraW5nZG9tIG5hbWUNCmFyY09ubHlfUzY4IDwtIGZpbHRlcihTSUxWQV90YWJsZTY4LCBLaW5nZG9tID09ICJBcmNoYWVhIikgI1NlbGVjdCBvbmx5IHJvd3Mgd2hlcmUgS2luZ2RvbSBpcyBBcmNoYWVhLg0KUkRQX3RhYmxlNjggPC0gYWxsX2pvaW5lZF9SRFA2OFtvcmRlcihyYW5rKEtpbmdkb20pLFBoeWx1bSldICNzb3J0IGJ5IGtpbmdkb20gbmFtZQ0KYXJjT25seV9SNjggPC0gZmlsdGVyKFJEUF90YWJsZTY4LCBLaW5nZG9tID09ICJCYWN0ZXJpYSIpICNTZWxlY3Qgb25seSByb3dzIHdoZXJlIEtpbmdkb20gaXMgQXJjaGFlYS4NCg0KJycnDQojb25seSBsb29rIGF0IG9yZGVycyBvZiBBcmNoYWVhDQphcmNPbmx5NDUgPC0gZmlsdGVyKFNJTFZBX3RhYmxlNDUsIEtpbmdkb20gPT0gIkFyY2hhZWEiKSAjU2VsZWN0IG9ubHkgcm93cyB3aGVyZSBLaW5nZG9tIGlzIEFyY2hhZWEuDQphcmNTb3J0NDUgPC0gYXJjT25seTQ1W29yZGVyKHJhbmsoQ291bnRzKSxPcmRlcildICNzb3J0IGJ5IGtpbmdkb20gbmFtZQ0KYXJjU29ydDQ1DQphcmNUb3AyMF80NSA8LSBzbGljZV90YWlsKGFyY1NvcnQ0NSwgbj0yMCkgI2dldCB0aGUgYm90dG9tIDIwIGNvdW50cyAoaXRzIGJ5IGFzY2VuZGluZyBvcmRlcikNCmFyY1RvcDIwXzQ1DQoNCiNWNlY4DQphcmNPbmx5NjggPC0gZmlsdGVyKFNJTFZBX3RhYmxlNjgsIEtpbmdkb20gPT0gIkFyY2hhZWEiKSAjU2VsZWN0IG9ubHkgcm93cyB3aGVyZSBLaW5nZG9tIGlzIEFyY2hhZWEuDQphcmNTb3J0NjggPC0gYXJjT25seTY4W29yZGVyKHJhbmsoQ291bnRzKSxPcmRlcildICNzb3J0IGJ5IGtpbmdkb20gbmFtZQ0KYXJjU29ydDY4DQphcmNUb3AyMF82OCA8LSBzbGljZV90YWlsKGFyY1NvcnQ2OCwgbj0yMCkgI2dldCB0aGUgYm90dG9tIDIwIGNvdW50cyAoaXRzIGJ5IGFzY2VuZGluZyBvcmRlcikNCmFyY1RvcDIwXzY4DQonJycNCiNkZWFsaW5nIHdpdGggZHVwZXMgYW5kIGRpc3RpbmN0IHZhbHVlczoNCiNodHRwczovL3d3dy5kYXRhbm92aWEuY29tL2VuL2xlc3NvbnMvaWRlbnRpZnktYW5kLXJlbW92ZS1kdXBsaWNhdGUtZGF0YS1pbi1yLw0KI3N1bW1pbmcNCiNodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy85Njc2MjEyL2hvdy10by1zdW0tZGF0YS1mcmFtZS1jb2x1bW4tdmFsdWVzDQoNCg0KI1Y0VjUgIyMjIyMjIyMjIyMjIyMjIyMjIw0KDQojU0lMVkEgIyMjDQphcmNoU3Vic2V0X1M0NSA8LSBzZWxlY3QoYXJjT25seTQ1LCBPcmRlcikgI09ubHkgZ2V0IHRoZSBuYW1lcyBvZiB0aGUgb3JkZXJzDQphcmNoRGlzdGluY3RfUzQ1IDwtIGRpc3RpbmN0KGFyY2hTdWJzZXRfUzQ1KSAjUmVtb3ZlcyBkdXBsaWNhdGVzLiBOb3cgaXQncyBhIGxpc3Qgb2YgZGlzdGluY3Qgb3JkZXJzLg0KYXJjaERpc3RpbmN0X1M0NQ0KDQpvcmRlck5hbWVzX1M0NSA8LSBjKCJMb2tpYXJjaGFlaWEiLCJCYXRoeWFyY2hhZWlhIiwiVGhlcm1vcGxhc21hdGEiLCJIYWxvYmFjdGVyaWEiLCJXb2VzZWFyY2hhZWlhIiwiTmFub2hhbG9hcmNoYWVpYSIsIk5pdHJvc29zcGhhZXJpYSIsIk1hcmluZSBCZW50aGljIEdyb3VwIEEiKQ0Kb3JkZXJTdW1zX1M0NSA8LSBjKCkgI3N1bXMgb2YgZWFjaCBvZiB0aGUgb3JkZXJzDQoNCiNsb29wIHRvIGZpbmQgdGhlIHN1bXMgb2YgZWFjaCBvcmRlciBhbmQgYWRkIHRvIHRoZSB2ZWN0b3INCmZvciAob05hbWUgaW4gb3JkZXJOYW1lc19TNDUpIHsNCiAgY3VyT3JkZXJUYWJsZSA8LSBmaWx0ZXIoU0lMVkFfdGFibGU0NSwgT3JkZXIgPT0gb05hbWUpICNTZWxlY3Qgb25seSByb3dzIHdpdGggdGhlIGN1cnJlbnQgb3JkZXIgbmFtZSBmcm9tIHRoZSBmdWxsIHRhYmxlDQogIGN1ck9yZGVyVGFibGUgPC0gc2VsZWN0KGN1ck9yZGVyVGFibGUsIE9yZGVyLCBDb3VudHMpICNtYWtlcyBhIHN1YiB0YWJsZSBvZiBvbmx5IHRoZSBjdXJyZW50IHRhYmxlJ3Mgb3JkZXIgbmFtZSBhbmQgY291bnRzDQogIA0KICBjdXJPcmRlclN1bSA8LSBzdW0oY3VyT3JkZXJUYWJsZSRDb3VudHMpICNzdW1zIGFsbCB0aGUgY291bnRzIG9mIHRoYXQgb3JkZXINCiAgb3JkZXJTdW1zX1M0NSA8LSBjKG9yZGVyU3Vtc19TNDUsIGN1ck9yZGVyU3VtKSANCn0NCihvcmRlclN1bXNfUzQ1KQ0KDQpvcmRlckRhdGFGcmFtZV9TNDUgPC0gZGF0YS5mcmFtZShvcmRlck5hbWVzX1M0NSwgb3JkZXJTdW1zX1M0NSkNCm9yZGVyRGF0YUZyYW1lX1M0NQ0KDQp0b3BBcmNoR3JhcGhfUzQ1IDwtZ2dwbG90KG9yZGVyRGF0YUZyYW1lX1M0NSwgYWVzKHg9b3JkZXJTdW1zX1M0NSwgeT1vcmRlck5hbWVzX1M0NSkpICsNCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArDQogIHRoZW1lX2xpZ2h0KCkNCnRvcEFyY2hHcmFwaF9TNDUNCg0KDQojUkRQICMjIyBUSEVSRSBBUkUgTk8gQVJDSEFFQT8/DQphcmNoU3Vic2V0X1I0NSA8LSBzZWxlY3QoYXJjT25seV9SNDUsIE9yZGVyKSAjT25seSBnZXQgdGhlIG5hbWVzIG9mIHRoZSBvcmRlcnMNCmFyY2hEaXN0aW5jdF9SNDUgPC0gZGlzdGluY3QoYXJjaFN1YnNldF9SNDUpICNSZW1vdmVzIGR1cGxpY2F0ZXMuIE5vdyBpdCdzIGEgbGlzdCBvZiBkaXN0aW5jdCBvcmRlcnMuDQphcmNoRGlzdGluY3RfUjQ1DQoNCm9yZGVyTmFtZXNfUjQ1IDwtYygpICNUaGVyZSBhcmUgbm8gYXJjaGFlYSBmcm9tIHRoZSBSRFAgZGF0YWJhc2UuLi4/DQpvcmRlclN1bXNfUjQ1IDwtIGMoKSAjc3VtcyBvZiBlYWNoIG9mIHRoZSBvcmRlcnMNCg0KI2xvb3AgdG8gZmluZCB0aGUgc3VtcyBvZiBlYWNoIG9yZGVyIGFuZCBhZGQgdG8gdGhlIHZlY3Rvcg0KZm9yIChvTmFtZSBpbiBvcmRlck5hbWVzX1I0NSkgew0KICBjdXJPcmRlclRhYmxlIDwtIGZpbHRlcihSRFBfdGFibGU0NSwgT3JkZXIgPT0gb05hbWUpICNTZWxlY3Qgb25seSByb3dzIHdpdGggdGhlIGN1cnJlbnQgb3JkZXIgbmFtZSBmcm9tIHRoZSBmdWxsIHRhYmxlDQogIGN1ck9yZGVyVGFibGUgPC0gc2VsZWN0KGN1ck9yZGVyVGFibGUsIE9yZGVyLCBDb3VudHMpICNtYWtlcyBhIHN1YiB0YWJsZSBvZiBvbmx5IHRoZSBjdXJyZW50IHRhYmxlJ3Mgb3JkZXIgbmFtZSBhbmQgY291bnRzDQogIA0KICBjdXJPcmRlclN1bSA8LSBzdW0oY3VyT3JkZXJUYWJsZSRDb3VudHMpICNzdW1zIGFsbCB0aGUgY291bnRzIG9mIHRoYXQgb3JkZXINCiAgb3JkZXJTdW1zX1I0NSA8LSBjKG9yZGVyU3Vtc19TNDUsIGN1ck9yZGVyU3VtKSANCn0NCihvcmRlclN1bXNfUjQ1KQ0KDQpvcmRlckRhdGFGcmFtZV9SNDUgPC0gZGF0YS5mcmFtZShvcmRlck5hbWVzX1I0NSwgb3JkZXJTdW1zX1I0NSkNCm9yZGVyRGF0YUZyYW1lX1I0NQ0KDQp0b3BBcmNoR3JhcGhfUzQ1IDwtZ2dwbG90KG9yZGVyRGF0YUZyYW1lX1M0NSwgYWVzKHg9b3JkZXJTdW1zX1M0NSwgeT1vcmRlck5hbWVzX1M0NSkpICsNCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArDQogIHRoZW1lX2xpZ2h0KCkNCnRvcEFyY2hHcmFwaF9TNDUNCg0KDQoNCg0KDQoNCg0KDQoNCiNWNlY4ICMjIyMjIyMjIyMjIyMjIyMjIyMNCg0KI1NJTFZBICMjIw0KYXJjaFN1YnNldCA8LSBzZWxlY3QoYXJjT25seTY4LCBPcmRlcikgI09ubHkgZ2V0IHRoZSBuYW1lcyBvZiB0aGUgb3JkZXJzDQphcmNoRGlzdGluY3QgPC0gZGlzdGluY3QoYXJjaFN1YnNldCkgI1JlbW92ZXMgZHVwbGljYXRlcy4gTm93IGl0J3MgYSBsaXN0IG9mIGRpc3RpbmN0IG9yZGVycy4NCmFyY2hEaXN0aW5jdA0KDQpvcmRlck5hbWVzX1M2OCA8LSBjKCJOaXRyb3NvcHVtaWxhbGVzIikNCm9yZGVyU3Vtc19TNjggPC0gYygpICNzdW1zIG9mIGVhY2ggb2YgdGhlIG9yZGVycw0KDQojbG9vcCB0byBmaW5kIHRoZSBzdW1zIG9mIGVhY2ggb3JkZXIgYW5kIGFkZCB0byB0aGUgdmVjdG9yDQpmb3IgKG9OYW1lIGluIG9yZGVyTmFtZXNfUzY4KSB7DQogIGN1ck9yZGVyVGFibGUgPC0gZmlsdGVyKFNJTFZBX3RhYmxlNjgsIE9yZGVyID09IG9OYW1lKSAjU2VsZWN0IG9ubHkgcm93cyB3aXRoIHRoZSBjdXJyZW50IG9yZGVyIG5hbWUgZnJvbSB0aGUgZnVsbCB0YWJsZQ0KICBjdXJPcmRlclRhYmxlIDwtIHNlbGVjdChjdXJPcmRlclRhYmxlLCBPcmRlciwgQ291bnRzKSAjbWFrZXMgYSBzdWIgdGFibGUgb2Ygb25seSB0aGUgY3VycmVudCB0YWJsZSdzIG9yZGVyIG5hbWUgYW5kIGNvdW50cw0KICANCiAgY3VyT3JkZXJTdW0gPC0gc3VtKGN1ck9yZGVyVGFibGUkQ291bnRzKSAjc3VtcyBhbGwgdGhlIGNvdW50cyBvZiB0aGF0IG9yZGVyDQogIG9yZGVyU3Vtc19TNjggPC0gYyhvcmRlclN1bXNfUzY4LCBjdXJPcmRlclN1bSkgDQp9DQoob3JkZXJTdW1zX1M2OCkNCg0Kb3JkZXJEYXRhRnJhbWVfUzY4IDwtIGRhdGEuZnJhbWUob3JkZXJOYW1lc19TNjgsIG9yZGVyU3Vtc19TNjgpDQpvcmRlckRhdGFGcmFtZV9TNjgNCg0KdG9wQXJjaEdyYXBoX1M2OCA8LWdncGxvdChvcmRlckRhdGFGcmFtZV9TNjgsIGFlcyh4PW9yZGVyU3Vtc19TNjgsIHk9b3JkZXJOYW1lc19TNjgpKSArDQogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKw0KICB0aGVtZV9saWdodCgpDQp0b3BBcmNoR3JhcGhfUzY4DQoNCg0KI1RoZXJlIGlzIG5vIGFyY2hhZWEgaXMgUkRQIG9mIFY2VjgNCg0KYGBgDQoNCmBgYHtyfQ0KI1RPRE8NCiNQaHlsb3NlcSB0byBnZXQgYWxwaGEgZGl2ZXJzaXR5DQpsaWJyYXJ5KHBoeWxvc2VxKQ0KDQpvdHVfbWF0PC0gcmVhZC5jc3YoIkc6L0Rlc2t0b3AvRm9sZGVycy9FZHUvMl0gRUFTL1RoZXNpcy9SZWFsX0NvbnRlbnQvRGF0YV9GaWxlcy9WNFY1L1Y0VjVfX0FTVl90YWJsZS5jc3YiLCBoZWFkZXIgPSBULCByb3cubmFtZXMgPSAxKSAjLHJvdy5uYW1lcz0xDQp0YXhfbWF0IDwtICByZWFkLmNzdigiRzovRGVza3RvcC9Gb2xkZXJzL0VkdS8yXSBFQVMvVGhlc2lzL1JlYWxfQ29udGVudC9EYXRhX0ZpbGVzL1Y0VjUvVjRWNV9TSUxWQV90YXhvbm9teS5jc3YiLCBoZWFkZXIgPSBULCByb3cubmFtZXMgPSAxKQ0Kc2FtcGxlc19kZjwtcmVhZC5jc3YoIkc6L0Rlc2t0b3AvRm9sZGVycy9FZHUvMl0gRUFTL1RoZXNpcy9SZWFsX0NvbnRlbnQvRGF0YV9GaWxlcy9WNFY1L21ldGFkYXRhXzE2U19WNFY1X2pvbmVzU291bmQyMDE5LnR4dCIsIHNlcCA9ICIiKQ0KDQpoZWFkKHRheF9tYXQpDQpoZWFkKG90dV9tYXQpDQoNCiNhc3NpZ24gcm93IG5hbWVzDQpyb3cubmFtZXMob3R1X21hdCkgPC0gb3R1X21hdCRPVFVJRA0KI3Jvdy5uYW1lcyh0YXhfbWF0KSA8LSB0YXhfbWF0JE9UVUlEDQojcm93Lm5hbWVzKHNhbXBsZXNfZGYpIDwtIHNhbXBsZXNfZGYkU2l0ZQ0KDQojVHJhbnNmb3JtIGludG8gbWF0cml4ZXMgb3R1IGFuZCB0YXggdGFibGVzIChzYW1wbGUgdGFibGUgY2FuIGJlIGxlZnQgYXMgZGF0YSBmcmFtZSkNCm90dV9tYXQgPC0gYXMubWF0cml4KG90dV9tYXQpDQojdGF4X21hdCA8LSBhcy5tYXRyaXgodGF4X21hdCkNCg0KY2xhc3ModGF4X21hdCkNCg0KI1RyYW5zZm9ybSB0byBwaHlsb3NlcSBvYmplY3RzDQpjbGFzcyhvdHVfbWF0KSA8LSAibnVtZXJpYyIgI05FRUQgdG8gY29udmVydCB0byBudW1lcmljIGluIHRoaXMgd2F5LiBIYXZlIHRvIHJ1biB3aG9sZSBjaHVuay4NCg0KT1RVID0gb3R1X3RhYmxlKG90dV9tYXQsIHRheGFfYXJlX3Jvd3MgPSBUUlVFKQ0KVEFYID0gdGF4X3RhYmxlKHRheF9tYXQpDQpzYW1wbGVzID0gc2FtcGxlX2RhdGEoc2FtcGxlc19kZikNCg0KaGVhZChPVFUpDQpoZWFkKFRBWCkNCg0KI3RheGFfbmFtZXMoT1RVKQ0Kc2FtcGxlX25hbWVzKE9UVSkNCnNhbXBsZV9uYW1lcyhUQVgpDQoNCnRheGFfbmFtZXMoT1RVKQ0KdGF4YV9uYW1lcyhUQVgpDQoNCiNDb252ZXJ0IHBoeWxvc2VxDQpQZXJtYSA8LSBwaHlsb3NlcShPVFUsIFRBWCwgc2FtcGxlcykNClBlcm1hDQoNCg0KDQoNCg0KDQpgYGANCg0KYGBge3J9DQojTWFraW5nIEJ1YmJsZSBwbG90cyAoVE9ETykNCg0KI1Y0VjUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyMjcmVhZCBpbiBvdHUgdGFibGUgb2YgVjRWNQ0Kb3R1NDU8LSByZWFkLmNzdigiRzovRGVza3RvcC9Gb2xkZXJzL0VkdS8yXSBFQVMvVGhlc2lzL1JlYWxfQ29udGVudC9EYXRhX0ZpbGVzL1Y0VjUvVjRWNV9fQVNWX3RhYmxlLmNzdiIpICMscm93Lm5hbWVzPTENCmhlYWQob3R1NDUpIA0KI0NvbnZlcnQgdG8gbG9uZyBmb3JtYXQNCm90dV9sb25nNDU8LWdhdGhlcihvdHU0NSwgU2FtcGxlLCBDb3VudHMsICJYMTIyIjoiWDgzIikgI2Rhc2hlcyBnb3QgY2hhbmdlZCB0byBkb3RzIGZvciBzb21lIHJlYXNvbg0KI21ha2UgYSBkYXRhLiBUYWJsZQ0Kb3R1X2xvbmc0NTwtYXMuZGF0YS50YWJsZShvdHVfbG9uZzQ1KQ0Kb3R1X2xvbmc0NQ0KDQojIyNyZWFkIGluIFY0VjVfU0lMVkFfdGF4b25vbXkuY3N2DQp0YXhvbm9teTQ1IDwtIHJlYWQuY3N2KCJHOi9EZXNrdG9wL0ZvbGRlcnMvRWR1LzJdIEVBUy9UaGVzaXMvUmVhbF9Db250ZW50L0RhdGFfRmlsZXMvVjRWNS9WNFY1X1NJTFZBX3RheG9ub215LmNzdiIpDQpoZWFkKHRheG9ub215NDUpDQojbWFrZSBhIGRhdGEudGFibGUNCnRheG9ub215NDU8LWFzLmRhdGEudGFibGUodGF4b25vbXk0NSkNCnRheG9ub215NDUNCg0KIyMjcmVhZCBpbiBtZXRhZGF0YSBmaWxlDQptZXRhRDQ1PC1yZWFkLmNzdjIoIkc6L0Rlc2t0b3AvRm9sZGVycy9FZHUvMl0gRUFTL1RoZXNpcy9SZWFsX0NvbnRlbnQvRGF0YV9GaWxlcy9WNFY1L21ldGFkYXRhXzE2U19WNFY1X2pvbmVzU291bmQyMDE5LnR4dCIpDQptZXRhRDQ1PC1hcy5kYXRhLnRhYmxlKG1ldGFENDUpDQpoZWFkKG1ldGFENDUpDQoNCg0Kd3JpdGUuY3N2KG90dV9sb25nNDUsICJHOi9EZXNrdG9wL0ZvbGRlcnMvRWR1LzJdIEVBUy9UaGVzaXMvUmVhbF9Db250ZW50L0RhdGFfRmlsZXMvVjRWNS9mb3JfcGxvdDQ1LmNzdiIpDQojcmVtb3ZlIDBzDQpmb3JfcGxvdDQ1IDwtIGZpbHRlcihvdHVfbG9uZzQ1LCBDb3VudHMhPSAwKQ0KI2ZvciByZWxhdGl2ZSBhYnVuZGFuY2U6DQojY2hhbmdlICJOYW1lIiBmb3IgdGhlIG5hbWUgb2YgeW91ciBjb2x1bW4gd2l0aCBncm91cCBkZXNjcmlwdGlvbg0KZm9yX3Bsb3Q0NSR0eXBlPC1hcy5mYWN0b3IoZm9yX3Bsb3Q0NSR0eXBlKQ0KI29yZGVyDQpmb3JfcGxvdDQ1JHR5cGU8LWZhY3Rvcihmb3JfcGxvdDQ1JHR5cGUsIGxldmVscz1jKCAicml2ZXIiLCAibmF0dXJhbCBiaW9maWxtIiwgImFydGlmaWNpYWwgYmlvZmlsbSIpKQ0KI05vdyBvcmRlciB5b3VyIHggYXhpcyAoc2l0ZSBuYW1lcykgPC0tIGVkaXQgYWNjb3JkaW5nbHkuDQpmb3JfcGxvdDQ1JFNpdGUgPC0gZmFjdG9yKGZvcl9wbG90NDUkU2l0ZSwgbGV2ZWxzID0gYyggIlNpZl8xIiwiU0lfMiIsIlNJXzMiLCAiUzRfMSIsICJCaWdfMSIsICJCSF8yIiwgIkJIXzMiLCAiUmFtXzEiLCJSQU1fMyIsICJCYXB0XzEiLCAiQlBfMiIsICJCUF8zIiwgIk5vcmRfMSIsICJOXzIiLCAiTl8zIiwgIlJvc2VfMSIsICJSTVNfMSIsICJSTVNfMiIsICJSTV8zIiwgIk1NXzEiLCAiTW9kXzEiLCAiTU1fMiIsICJNTV8zIiwgIlRNXzEiLCAiVF8yIiwgIlNNXzIiLCAiV2hpdGVfMSIsICJXTV8yIiwgIldNXzMiLCAiR01fMSIsICJTdHVyZ18xIiwgIlNUXzIiLCAiVmVybV8xIiwgIlZNXzEiLCAiVkFfMSIsICJWTV8yIiwgIlZNXzMiLCAiVjNfMSIpKQ0KDQojc3dlZXQtIG5vdyBwbG90IChub3RlIHRoYXQgdGhpcyBpcyBmb3IgcmF3IGNvdW50czsgY2hhbmdlIGZvciByZWxhdGl2ZSBhYnVuZGFuY2UpDQp0aGVtZV9zZXQodGhlbWVfYncoKSkNCmNvbD1jKCAiZ3JlZW4iLCJvcmFuZ2UiLCAicHVycGxlIikjIyA8LSBjaGFuZ2UgYWNjb3JkaW5nbHksIGlmIGRlc2lyZWQtLSBzZWUgaHR0cDovL3d3dy5zdGF0LmNvbHVtYmlhLmVkdS9+dHpoZW5nL2ZpbGVzL1Jjb2xvci5wZGYNCmcgPC0gZ2dwbG90KGZvcl9wbG90NDUsIGFlcyh4PVNhbXBsZSwgeT1TYW1wbGUpKSANCmcgKyBnZW9tX3BvaW50KGFlcyhzaXplPUNvdW50cykpICsNCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXM9Y29sKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCBzaXplPTkpKSsNCiAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoIHNpemU9OSkpKw0KICB0aGVtZShheGlzLnRpdGxlLng9ZWxlbWVudF90ZXh0KHNpemU9MTIpKSsNCiAgdGhlbWUoYXhpcy50aXRsZS55PWVsZW1lbnRfdGV4dChzaXplPTEyKSkNCiNleHBvcnQgYm90aCBidWJibGUgcGxvdHMgYXMgUERGLg0KDQoNCiNWNlY4IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMjI3JlYWQgaW4gb3R1IHRhYmxlIG9mIFY2VjggDQpvdHU2ODwtIHJlYWQuY3N2KCJHOi9EZXNrdG9wL0ZvbGRlcnMvRWR1LzJdIEVBUy9UaGVzaXMvUmVhbF9Db250ZW50L0RhdGFfRmlsZXMvVjZWOC9WNlY4X19BU1ZfdGFibGUuY3N2IikgIyxyb3cubmFtZXM9MQ0KaGVhZChvdHU2OCkgDQojQ29udmVydCB0byBsb25nIGZvcm1hdA0Kb3R1X2xvbmc2ODwtZ2F0aGVyKG90dTY4LCBTYW1wbGUsIENvdW50cywgIlgxMjIubyI6Ilg4My5vIikgI2Rhc2hlcyBnb3QgY2hhbmdlZCB0byBkb3RzIGZvciBzb21lIHJlYXNvbg0KI21ha2UgYSBkYXRhLiBUYWJsZQ0Kb3R1X2xvbmc2ODwtYXMuZGF0YS50YWJsZShvdHVfbG9uZzY4KQ0Kb3R1X2xvbmc2OA0KDQojIyNyZWFkIGluIGJpb20tdGF4b25vbXkNCnRheG9ub215NjggPC0gcmVhZC5jc3YoIkc6L0Rlc2t0b3AvRm9sZGVycy9FZHUvMl0gRUFTL1RoZXNpcy9SZWFsX0NvbnRlbnQvRGF0YV9GaWxlcy9WNlY4L3RheG9ub215X1NJTFZBX1Y2VjguY3N2IikNCmhlYWQodGF4b25vbXk2OCkNCiNtYWtlIGEgZGF0YS50YWJsZQ0KdGF4b25vbXk8LWFzLmRhdGEudGFibGUodGF4b25vbXk2OCkNCnRheG9ub215NjgNCg0KIyMjcmVhZCBpbiBtZXRhZGF0YSBmaWxlDQptZXRhRDY4PC1yZWFkLmNzdjIoIkc6L0Rlc2t0b3AvRm9sZGVycy9FZHUvMl0gRUFTL1RoZXNpcy9SZWFsX0NvbnRlbnQvRGF0YV9GaWxlcy9WNlY4L21ldGFkYXRhXzE2U19WNlY4X2pvbmVzU291bmQyMDE5Qy5jc3YiKSANCm1ldGFENjg8LWFzLmRhdGEudGFibGUobWV0YUQ2OCkNCmhlYWQobWV0YUQ2OCkNCg0KDQoNCndyaXRlLmNzdihvdHVfbG9uZzY4LCJHOi9EZXNrdG9wL0ZvbGRlcnMvRWR1LzJdIEVBUy9UaGVzaXMvUmVhbF9Db250ZW50L0RhdGFfRmlsZXMvVjZWOC9mb3JfcGxvdDY4LmNzdiIpDQp2NjggPC0gcmVhZC5jc3YoIkc6L0Rlc2t0b3AvRm9sZGVycy9FZHUvMl0gRUFTL1RoZXNpcy9SZWFsX0NvbnRlbnQvRGF0YV9GaWxlcy9WNlY4L2Zvcl9wbG90NjguY3N2IikNCnY2OA0KDQojcmVtb3ZlIDBzDQpmb3JfcGxvdDY4IDwtIGZpbHRlcihvdHVfbG9uZzY4LCBDb3VudHMhPSAwKQ0KI2ZvciByZWxhdGl2ZSBhYnVuZGFuY2U6DQojY2hhbmdlICJOYW1lIiBmb3IgdGhlIG5hbWUgb2YgeW91ciBjb2x1bW4gd2l0aCBncm91cCBkZXNjcmlwdGlvbg0KZm9yX3Bsb3Q2OCR0eXBlPC1hcy5mYWN0b3IoZm9yX3Bsb3Q2OCR0eXBlKQ0KI29yZGVyDQpmb3JfcGxvdDY4JHR5cGU8LWZhY3Rvcihmb3JfcGxvdDY4JHR5cGUsIGxldmVscz1jKCAicml2ZXIiLCAibmF0dXJhbCBiaW9maWxtIiwgImFydGlmaWNpYWwgYmlvZmlsbSIpKQ0KI05vdyBvcmRlciB5b3VyIHggYXhpcyAoc2l0ZSBuYW1lcykgPC0tIGVkaXQgYWNjb3JkaW5nbHkuDQpmb3JfcGxvdDY4JFNpdGUgPC0gZmFjdG9yKGZvcl9wbG90NjgkU2l0ZSwgbGV2ZWxzID0gYyggIlNpZl8xIiwiU0lfMiIsIlNJXzMiLCAiUzRfMSIsICJCaWdfMSIsICJCSF8yIiwgIkJIXzMiLCAiUmFtXzEiLCJSQU1fMyIsICJCYXB0XzEiLCAiQlBfMiIsICJCUF8zIiwgIk5vcmRfMSIsICJOXzIiLCAiTl8zIiwgIlJvc2VfMSIsICJSTVNfMSIsICJSTVNfMiIsICJSTV8zIiwgIk1NXzEiLCAiTW9kXzEiLCAiTU1fMiIsICJNTV8zIiwgIlRNXzEiLCAiVF8yIiwgIlNNXzIiLCAiV2hpdGVfMSIsICJXTV8yIiwgIldNXzMiLCAiR01fMSIsICJTdHVyZ18xIiwgIlNUXzIiLCAiVmVybV8xIiwgIlZNXzEiLCAiVkFfMSIsICJWTV8yIiwgIlZNXzMiLCAiVjNfMSIpKQ0KDQojc3dlZXQtIG5vdyBwbG90IChub3RlIHRoYXQgdGhpcyBpcyBmb3IgcmF3IGNvdW50czsgY2hhbmdlIGZvciByZWxhdGl2ZSBhYnVuZGFuY2UpDQp0aGVtZV9zZXQodGhlbWVfYncoKSkNCmNvbD1jKCAiZ3JlZW4iLCJvcmFuZ2UiLCAicHVycGxlIikjIyA8LSBjaGFuZ2UgYWNjb3JkaW5nbHksIGlmIGRlc2lyZWQtLSBzZWUgaHR0cDovL3d3dy5zdGF0LmNvbHVtYmlhLmVkdS9+dHpoZW5nL2ZpbGVzL1Jjb2xvci5wZGYNCmcgPC0gZ2dwbG90KGZvcl9wbG90NjgsIGFlcyh4PVNhbXBsZSwgeT1TYW1wbGUpKSNjb2xvdXI9dHlwZQ0KZyArIGdlb21fcG9pbnQoYWVzKHNpemU9Q291bnRzKSkgKw0KICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1jb2wpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIHNpemU9OSkpKw0KICB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dCggc2l6ZT05KSkrDQogIHRoZW1lKGF4aXMudGl0bGUueD1lbGVtZW50X3RleHQoc2l6ZT0xMikpKw0KICB0aGVtZShheGlzLnRpdGxlLnk9ZWxlbWVudF90ZXh0KHNpemU9MTIpKQ0KI2V4cG9ydCBib3RoIGJ1YmJsZSBwbG90cyBhcyBQREYuDQpgYGANCg0KYGBge3J9DQojTk1EUw0KI2V4YW1wbGUgd2l0aCByYW5kb21pemVkIHRhYmxlIGZyb20gaHR0cHM6Ly9qb25sZWZjaGVjay5uZXQvMjAxMi8xMC8yNC9ubWRzLXR1dG9yaWFsLWluLXIvDQoNCiNvbiBteSBkYXRhOg0Kb3R1X29nMzwtIHJlYWQuY3N2KCJHOi9EZXNrdG9wL0ZvbGRlcnMvRWR1LzJdIEVBUy9UaGVzaXMvUmVhbF9Db250ZW50L0RhdGFfRmlsZXMvYm90aF9BU1ZfdGFibGVzMy5jc3YiLCByb3cubmFtZXMgPSAxKSAjTm93IHdpdGggdGhlIHJlYWwgZGF0YQ0KDQpvdHVfb2czDQpuY29sKG90dV9vZzMpDQpoZWFkKG90dV9vZzMpDQoNCm90dSA8LSB0KG90dV9vZzMpICN0cmFuc3Bvc2UNCmNsYXNzKG90dSkNCm5yb3cob3R1KQ0KI2hlYWQob3R1KQ0KDQpyb3duYW1lcyhvdHUpDQoNCiNzZXQgZ3JvdXBpbmcgaW5mbw0KZ3JvdXBpbmdfaW5mbyA8LSBkYXRhLmZyYW1lKHJvdy5uYW1lcz0ocm93bmFtZXMob3R1KSksdChhcy5kYXRhLmZyYW1lKHN0cnNwbGl0KHJvd25hbWVzKG90dSksIl8iKSkpKQ0KY2xhc3MoZ3JvdXBpbmdfaW5mbykNCmdyb3VwaW5nX2luZm8NCg0KI2NsYXNzKG90dSk8LSgibnVtZXJpYyIpICNuZWVkZWQgd2hlbiByb3cgbmFtZXMgd2VyZW4ndCByZW1vdmVkDQpvdHVfdHJpbSA8LSBuYS5vbWl0KG90dSkgI3RyaW0gZXh0cmEgbWlzc2luZyBkYXRhIGFzIHBlciBodHRwczovL3N0YXQuZXRoei5jaC9waXBlcm1haWwvci1oZWxwLy8yMDEzLU1heS8zNTMyMTAuaHRtbA0KbnJvdyhvdHVfdHJpbSkNCg0KbXlfTk1EUzwtbWV0YU1EUyhvdHUsZGlzdGFuY2UgPSAiYnJheSIsIGsgPSAyLCB0cnltYXggPSA1MCkNCg0KI1ZpZXcgTk1EUyBzdHJhaWdodCwgY2hlY2sgY29ycmVjdG5lc3MNCm15X05NRFMNCnN0cmVzc3Bsb3QobXlfTk1EUykNCnBsb3QobXlfTk1EUykNCm5yb3cobXlfTk1EUyRwb2ludHMpDQoNCiNleHRyYWN0IE5NRFMgc2NvcmVzICh4IGFuZCB5IGNvb3JkaW5hdGVzKQ0KZGF0YS5zY29yZXMgPSBhcy5kYXRhLmZyYW1lKHNjb3JlcyhteV9OTURTKSkNCmNvbG5hbWVzKGRhdGEuc2NvcmVzKQ0KDQpuY29sKGdyb3VwaW5nX2luZm8pDQoNCiNtZXRhTURTIGRvY3VtZW50YXRpb24gZnVsbDogaHR0cHM6Ly93d3cucmRvY3VtZW50YXRpb24ub3JnL3BhY2thZ2VzL3ZlZ2FuL3ZlcnNpb25zLzEuMTUtMS90b3BpY3MvbWV0YU1EUw0KI2ZyYW1pbmcgdGhlIE5NRFMgZGF0YQ0KTk1EUz1kYXRhLmZyYW1lKHg9bXlfTk1EUyRwb2ludFssMV0seT1teV9OTURTJHBvaW50WywyXSkgI09ubHkgdXNlcyBwb2ludCBkYXRhIChyZXN0IGlzIG5vdCByZWxldmFudCBpbiB0aGlzIGNhc2UpLg0KDQoNCiNMaXN0cyBhcmUgY29sdW1ucyBvZiB0aGUgbWV0YWRhdGEgdGFibGUgZm9yIFY0VjUuIFVzZWQgZm9yIG1ha2luZyB0aGUgTk1EUyB0YWJsZQ0KDQpTYW1wbGVOYW1lVjRWNTwtYygiM19TNTEiLCI1X1MyMSIsIjZfUzUzIiwiOF9TNTQiLCIxNF9TMTI0IiwiMTZfUzkwIiwiMjBfUzQ3IiwiMjNfUzg4IiwiMjVfUzM4IiwiMjlfUzg1IiwiMzFfUzkxIiwiMzJfUzg5IiwiMzNfUzg2IiwiMzdfUzc4IiwiMzlfUzMzIiwiNDNfUzM0IiwiNDZfUzc5IiwiNDhfUzgwIiwiNTZfUzc3IiwiNTdfUzY3IiwiNjVfUzY5IiwiNzVfUzI1IiwiODFfUzcwIiwiODNfUzI4IiwiMTIyX1MxMjciLCIxNTVfUzEwNCIsIjE1N19TMTE5IikNClNhbXBsZU5hbWVWNlY4PC1jKCJjMy1vX1MxNiIsIjUtb19TMTYiLCI2LW9fUzE5IiwiOC1vX1M0IiwiMTQtb19TNjMiLCIxNi1vX1MxOCIsIjIwLW9fUzY0IiwiMjMtb19TNjUiLCIyNS1vX1M1NyIsIjI5LW9fUzciLCIzMS1vX1MyMCIsIjMyLW9fUzUiLCIzMy1vX1M2IiwiMzctb19TNjEiLCIzOS1vX1MxMSIsIjQzLW9fUzEwIiwiNDYtb19TNjAiLCI0OC1vX1M1OSIsIjU2LW9fUzgiLCI1Ny1vX1M2MiIsIjY1LW9fUzE0IiwiNzUtb19TNTgiLCI4MS1vX1M2NiIsIjgzLW9fUzEzIiwiMTIyLW9fUzE3IiwiMTU1LW9fUzMiLCIxNTctb19TMTUiKQ0KU2FtcGxlTmFtZSA8LSBjKFNhbXBsZU5hbWVWNFY1LFNhbXBsZU5hbWVWNlY4KSAjY29tYmluZSB0aGUgdHdvIHZlY3RvcnMgZnJvbSBWNFY1IGFuZCBWNlY4DQoNCg0KVHJhbnNlY3RWNFY1PC1jKCJTdmVyZHJ1cF9kaXN0YWwiLCJGcmFtX0Zpb3JkIiwiU3ZlcmRydXBfZGlzdGFsIiwiU3ZlcmRydXBfZGlzdGFsIiwiRnJhbV9GaW9yZCIsIlN2ZXJkcnVwX2Rpc3RhbCIsIlN2ZXJkcnVwX2dsYWNpZXIiLCJTdmVyZHJ1cF9nbGFjaWVyIiwiU3ZlcmRydXBfZ2xhY2llcl9yZXBlYXQiLCJTdmVyZHJ1cF9nbGFjaWVyIiwiU3ZlcmRydXBfZGlzdGFsIiwiU3ZlcmRydXBfZ2xhY2llciIsIlN2ZXJkcnVwX2dsYWNpZXIiLCJTdmVyZHJ1cF9nbGFjaWVyIiwiQmVsY2hlcl80IiwiQmVsY2hlcl80IiwiU3ZlcmRydXBfZ2xhY2llciIsIlN2ZXJkcnVwX2dsYWNpZXIiLCJCZWxjaGVyXzQiLCJKYWtlbWFuXzQiLCJKYWtlbWFuXzUiLCJGcmFtX0Zpb3JkIiwiSmFrZW1hbl81IiwiQmVsY2hlcl8xIiwiU3ViZ2xhY2lhbCIsIlN5ZGthcF8zIiwiR3Jpc2VfRmlvcmRfMiIpDQpUcmFuc2VjdFY2Vjg8LWMoIlN2ZXJkcnVwX2Rpc3RhbCIsIkZyYW1fRmlvcmQiLCJTdmVyZHJ1cF9kaXN0YWwiLCJTdmVyZHJ1cF9kaXN0YWwiLCJGcmFtX0Zpb3JkIiwiU3ZlcmRydXBfZGlzdGFsIiwiU3ZlcmRydXBfZ2xhY2llciIsIlN2ZXJkcnVwX2dsYWNpZXIiLCJTdmVyZHJ1cF9nbGFjaWVyX3JlcGVhdCIsIlN2ZXJkcnVwX2dsYWNpZXIiLCJTdmVyZHJ1cF9kaXN0YWwiLCJTdmVyZHJ1cF9nbGFjaWVyIiwiU3ZlcmRydXBfZ2xhY2llciIsIlN2ZXJkcnVwX2dsYWNpZXIiLCJCZWxjaGVyXzQiLCJCZWxjaGVyXzQiLCJTdmVyZHJ1cF9nbGFjaWVyIiwiU3ZlcmRydXBfZ2xhY2llciIsIkJlbGNoZXJfNCIsIkpha2VtYW5fNCIsIkpha2VtYW5fNSIsIkZyYW1fRmlvcmQiLCJKYWtlbWFuXzUiLCJCZWxjaGVyXzEiLCJTdWJnbGFjaWFsIiwiU3lka2FwXzMiLCJHcmlzZV9GaW9yZF8yIikNClRyYW5zZWN0IDwtIGMoVHJhbnNlY3RWNFY1LFRyYW5zZWN0VjZWOCkNCg0KRGVwdGhWNFY1PC1jKCIxNSIsICI1IiwgIjUwIiwgIjIwMCIsICIxMCIsICIxMjUiLCI0NyIsICI0MCIsICIxNyIsIjQiLCAiMzUwIiwgIjY3IiwiMTIiLCAiNyIsICI1IiwgIjIwIiwgIjIwIiwgIjExNSIsICIxNDAiLCAiNSIsICI1IiwgIjAiLCAiMjciLCAiOTUiLCAiMTEyIiwgIjciLCAiMTQ1IikNCkRlcHRoVjZWODwtYygiMTUiLCAiNSIsICI1MCIsICIyMDAiLCAiMTAiLCAiMTI1IiwiNDciLCAiNDAiLCAiMTciLCI0IiwgIjM1MCIsICI2NyIsIjEyIiwgIjciLCAiNSIsICIyMCIsICIyMCIsICIxMTUiLCAiMTQwIiwgIjUiLCAiNSIsICIwIiwgIjI3IiwgIjk1IiwgIjExMiIsICI3IiwgIjE0NSIpDQpEZXB0aCA8LSBjKERlcHRoVjRWNSxEZXB0aFY2VjgpDQoNClN0YXRpb25WNFY1PC0gYygiVklPXzMzIiwiVklPXzIiLCJWSU9fMzMiLCJWSU9fMzMiLCJWSU9fMiIsIlZJT18zMiIsIlZJT18zMCIsIlZJT18zMSIsIlZJT18yNCIsIlZJT18yOCIsIlZJT18zMiIsIlZJT18zMSIsIlZJT18yOCIsIlZJT18yMiIsIlZJT18xMyIsIlZJT18xMyIsIlZJT18yMiIsIlZJT18yMiIsIlZJT18xMyIsIlZJT182IiwiVklPXzciLCJWSU9fOSIsIlZJT183IiwiVklPXzEwIiwiR2xhY2lhbF9zYW1wbGUiLCJWSU9fMzkiLCJWSU9fNDQiKQ0KU3RhdGlvblY2Vjg8LSBjKCJWSU9fMzMiLCJWSU9fMiIsIlZJT18zMyIsIlZJT18zMyIsIlZJT18yIiwiVklPXzMyIiwiVklPXzMwIiwiVklPXzMxIiwiVklPXzI0IiwiVklPXzI4IiwiVklPXzMyIiwiVklPXzMxIiwiVklPXzI4IiwiVklPXzIyIiwiVklPXzEzIiwiVklPXzEzIiwiVklPXzIyIiwiVklPXzIyIiwiVklPXzEzIiwiVklPXzYiLCJWSU9fNyIsIlZJT185IiwiVklPXzciLCJWSU9fMTAiLCJHbGFjaWFsX3NhbXBsZSIsIlZJT18zOSIsIlZJT180NCIpDQpTdGF0aW9uIDwtIGMoU3RhdGlvblY0VjUsU3RhdGlvblY2VjgpDQoNCklEVjRWNTwtYygiMyIsIjUiLCI2IiwiOCIsIjE0IiwiMTYiLCIyMCIsIjIzIiwiMjUiLCIyOSIsIjMxIiwiMzIiLCIzMyIsIjM3IiwiMzkiLCI0MyIsIjQ2IiwiNDgiLCI1NiIsIjU3IiwiNjUiLCI3NSIsIjgxIiwiODMiLCIxMjIiLCIxNTUiLCIxNTciKQ0KSURWNlY4PC1jKCIzLW8iLCI1LW8iLCI2LW8iLCI4LW8iLCIxNC1vIiwiMTYtbyIsIjIwLW8iLCIyMy1vIiwiMjUtbyIsIjI5LW8iLCIzMS1vIiwiMzItbyIsIjMzLW8iLCIzNy1vIiwiMzktbyIsIjQzLW8iLCI0Ni1vIiwiNDgtbyIsIjU2LW8iLCI1Ny1vIiwiNjUtbyIsIjc1LW8iLCINCjgxLW8iLCI4My1vIiwiMTIyLW8iLCIxNTUtbyIsIjE1Ny1vIikNCklEIDwtIGMoSURWNFY1LElEVjZWOCkNCg0KUHJpbWVyIDwtIGMoIlY0VjUiLCJWNFY1IiwiVjRWNSIsIlY0VjUiLCJWNFY1IiwiVjRWNSIsIlY0VjUiLCJWNFY1IiwiVjRWNSIsIlY0VjUiLCJWNFY1IiwiVjRWNSIsIlY0VjUiLCJWNFY1IiwiVjRWNSIsIlY0VjUiLCJWNFY1IiwiVjRWNSIsIlY0VjUiLCJWNFY1IiwiVjRWNSIsIlY0VjUiLCJWNFY1IiwiVjRWNSIsIlY0VjUiLCJWNFY1IiwiVjRWNSIsIlY2VjgiLCJWNlY4IiwiVjZWOCIsIlY2VjgiLCJWNlY4IiwiVjZWOCIsIlY2VjgiLCJWNlY4IiwiVjZWOCIsIlY2VjgiLCJWNlY4IiwiVjZWOCIsIlY2VjgiLCJWNlY4IiwiVjZWOCIsIlY2VjgiLCJWNlY4IiwiVjZWOCIsIlY2VjgiLCJWNlY4IiwiVjZWOCIsIlY2VjgiLCJWNlY4IiwiVjZWOCIsIlY2VjgiLCJWNlY4IiwiVjZWOCIpDQoNCg0KI2FkZCB0aGlzIHRvIHlvdXIgTk1EUyBkYXRhIGZyYW1lIGFzIGEgbmV3IGNvbHVtbg0KTk1EUyRJRDwtSUQNCk5NRFMkU2FtcGxlTmFtZTwtU2FtcGxlTmFtZQ0KTk1EUyRUcmFuc2VjdDwtVHJhbnNlY3QNCk5NRFMkRGVwdGg8LURlcHRoDQpOTURTJFN0YXRpb248LVN0YXRpb24NCk5NRFMkUHJpbWVyPC1QcmltZXINCg0KI29yZGVyIHlvdXIgR3JvdXAgY29sdW1uIGFjY29yZGluZyB3aGF0IHlvdSB3b3VsZCBsaWtlLCBoZXJlIGZvciBleGFtcGxlLCBhY2NvcmRpbmcgdG8gIElEIG51bWJlcjoNCk5NRFMkSUQ8LWZhY3RvcihOTURTJElELCBsZXZlbHM9SUQpDQoNCk5NRFMgI1RoaXMgaXMgYSBkYXRhZnJhbWUgdGhhdCBoYXMgdGhlIG1ldGFkYXRhIG1hbnVhbGx5IG1lcmdlZCBpbnRvIGl0LCBhcyB3ZWxsIGFzIHRoZSBYIGFuZCBZIHZhbHVlcyBmcm9tIHRoZSBOTURTIGFuYWx5c2lzLiBUaGlzIGlzIHdoYXQgaXMgdXNlZCB0byBjcmVhdGUgdGhlIHBsb3QuDQoNCiNHcmFwaGluZyBOTURTDQojR3JhcGggd2l0aCBhbGwgdHJpbW1pbmdzDQpsaWJyYXJ5KGdncGxvdDIpDQoNCnh4ID0gZ2dwbG90KE5NRFMsIGFlcyh4ID0geCwgeSA9IHkpKSArIA0KICAgIGdlb21fcG9pbnQoYWVzKHNpemUgPSBhcy5udW1lcmljKERlcHRoKSwgc2hhcGUgPSBQcmltZXIsIGNvbG91ciA9IFRyYW5zZWN0KSkrDQogIA0KICAgIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICJibGFjayIsIHNpemUgPSAxMiwgZmFjZSA9ICJib2xkIiksIA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICJibGFjayIsIGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxMiksIA0KICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgZmFjZSA9ImJvbGQiLCBjb2xvdXIgPSJibGFjayIpLCANCiAgICBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDE0KSwgDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNCwgY29sb3VyID0gImJsYWNrIiksIA0KICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIGNvbG91ciA9ICJibGFjayIsIGZhY2UgPSAiYm9sZCIpLCANCiAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gImJsYWNrIiwgZmlsbCA9IE5BLCBzaXplID0gMS4yKSwNCiAgICBsZWdlbmQua2V5PWVsZW1lbnRfYmxhbmsoKSkgKyANCiAgICBsYWJzKHggPSAieCIsIGNvbG91ciA9ICJUcmFuc2VjdCIsIHkgPSAieSIsIHNoYXBlID0gIlByaW1lciIpICANCiANCnh4DQoNCg0KcHJpbWVyX29ubHkgPSBnZ3Bsb3QoTk1EUywgYWVzKHggPSB4LCB5ID0geSkpICsgDQogICAgZ2d0aXRsZSgiTk1EUyBvZiBzYW1wbGVzIGNvbXBhcmVkIGJ5IHByaW1lciIpKw0KICAgIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IFByaW1lciksIHNpemUgPSAzKSsNCiAgICBnZW9tX3BvaW50KHNoYXBlID0gMSxzaXplID0gMyxjb2xvdXIgPSAiYmxhY2siKSsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsPUlEKSxoanVzdD0xLjI1LCB2anVzdD0xLjI1LHNpemU9Mi41KSsNCg0KICANCiAgICB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSAiYmxhY2siLCBzaXplID0gMTIsIGZhY2UgPSAiYm9sZCIpLCANCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSAiYmxhY2siLCBmYWNlID0gImJvbGQiLCBzaXplID0gMTIpLCANCiAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGZhY2UgPSJib2xkIiwgY29sb3VyID0iYmxhY2siKSwgDQogICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNCksIA0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTQsIGNvbG91ciA9ICJibGFjayIpLCANCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0LCBjb2xvdXIgPSAiYmxhY2siLCBmYWNlID0gImJvbGQiKSwgDQogICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGNvbG91ciA9ICJibGFjayIsIGZpbGwgPSBOQSwgc2l6ZSA9IDEuMiksDQogICAgbGVnZW5kLmtleT1lbGVtZW50X2JsYW5rKCkpICsgDQogICAgbGFicyh4ID0gIngiLCB5ID0gInkiLCBjb2xvdXIgPSAiUHJpbWVyIikgIA0KIA0KcHJpbWVyX29ubHkNCg0KDQpgYGANCg0KYGBge3J9DQojRGF0YSBwcm9jZXNzaW5nIHdpdGggUHlsb3NlcTpodHRwczovL3ZhdWxvdC5naXRodWIuaW8vdHV0b3JpYWxzL1BoeWxvc2VxX3R1dG9yaWFsLmh0bWwNCg0KDQpvdHVfbWF0IDwtcmVhZC5jc3YoIkc6L0Rlc2t0b3AvRm9sZGVycy9FZHUvMl0gRUFTL1RoZXNpcy9FeGFtcGxlX0NvbnRlbnQvYWxsX09UVV9OTURTbnUuY3N2Iiwgcm93Lm5hbWVzPTEpIA0KdGF4X21hdCA8LSByZWFkLmNzdigiRzovRGVza3RvcC9Gb2xkZXJzL0VkdS8yXSBFQVMvVGhlc2lzL0V4YW1wbGVfQ29udGVudC9iaW9tLXRheG9ub215LmNzdiIsIHJvdy5uYW1lcz0xKQ0Kc2FtcGxlc19kZiAgPC0gYXMuZGF0YS5mcmFtZShyZWFkLmNzdigiRzovRGVza3RvcC9Gb2xkZXJzL0VkdS8yXSBFQVMvVGhlc2lzL0V4YW1wbGVfQ29udGVudC9hbGxfT1RVX05NRFMuY3N2IikpDQoNCmhlYWQob3R1X21hdCkNCmhlYWQoc2FtcGxlc19kZikNCg0KI2Fzc2lnbiByb3cgbmFtZXMNCnJvdy5uYW1lcyhvdHVfbWF0KSA8LSBvdHVfbWF0JE9UVUlEDQpyb3cubmFtZXModGF4X21hdCkgPC0gdGF4X21hdCRPVFVJRA0Kcm93Lm5hbWVzKHNhbXBsZXNfZGYpIDwtIHNhbXBsZXNfZGYkU2l0ZQ0KDQojVHJhbnNmb3JtIGludG8gbWF0cml4ZXMgb3R1IGFuZCB0YXggdGFibGVzIChzYW1wbGUgdGFibGUgY2FuIGJlIGxlZnQgYXMgZGF0YSBmcmFtZSkNCm90dV9tYXQgPC0gYXMubWF0cml4KG90dV9tYXQpDQp0YXhfbWF0IDwtIGFzLm1hdHJpeCh0YXhfbWF0KQ0KDQpjbGFzcyhvdHVfbWF0KQ0KDQojVHJhbnNmb3JtIHRvIHBoeWxvc2VxIG9iamVjdHMNCmNsYXNzKG90dV9tYXQpIDwtICJudW1lcmljIiAjTkVFRCB0byBjb252ZXJ0IHRvIG51bWVyaWMgaW4gdGhpcyB3YXkuIEhhdmUgdG8gcnVuIHdob2xlIGNodW5rLg0KDQpPVFUgPSBvdHVfdGFibGUob3R1X21hdCwgdGF4YV9hcmVfcm93cyA9IFRSVUUpDQpUQVggPSB0YXhfdGFibGUoYSkNCnNhbXBsZXMgPSBzYW1wbGVfZGF0YShzYW1wbGVzX2RmKQ0KDQpucm93KE9UVSkNCm5yb3coVEFYKQ0KbnJvdyhzYW1wbGVzKQ0KDQojQ29udmVydCBwaHlsb3NlcQ0KUGVybWEgPC0gcGh5bG9zZXEoT1RVLCBUQVgsIHNhbXBsZXMpDQpQZXJtYQ0KDQoNCg0KYGBgDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0K